├── .eslintignore
├── src
├── hooks
│ ├── index.tsx
│ └── useCandidates.tsx
├── types
│ ├── city.d.ts
│ ├── index.d.ts
│ └── candidate.d.ts
├── services
│ ├── index.ts
│ ├── get-candidates.ts
│ └── get-candidate.ts
├── lib
│ ├── api.ts
│ └── react-query.ts
├── components
│ ├── index.tsx
│ ├── SVG
│ │ ├── index.tsx
│ │ ├── empty-state-service.tsx
│ │ ├── empty-state-candidate.tsx
│ │ └── empty-state-location.tsx
│ ├── Footer
│ │ ├── styles.module.scss
│ │ └── index.tsx
│ ├── SEO
│ │ └── index.tsx
│ └── Layout
│ │ ├── index.tsx
│ │ └── styles.module.scss
├── pages
│ ├── [state]
│ │ └── [city]
│ │ │ ├── candidato
│ │ │ ├── components
│ │ │ │ ├── News
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Share
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Tags
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Breadcrumb
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── InfoPoliticalParty
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Properties
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── PreviousElections
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── styles.module.scss
│ │ │ │ ├── Skeleton
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ └── Profile
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ ├── styles.module.scss
│ │ │ └── [id].page.tsx
│ │ │ └── candidatos
│ │ │ ├── components
│ │ │ ├── Skeleton
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ │ ├── FilterMobile
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ │ ├── Candidates
│ │ │ │ ├── styles.module.scss
│ │ │ │ └── index.tsx
│ │ │ └── Aside
│ │ │ │ ├── styles.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── styles.module.scss
│ │ │ └── index.page.tsx
│ ├── _app.page.tsx
│ ├── nao-encontrado
│ │ ├── candidato.page.tsx
│ │ ├── styles.module.scss
│ │ └── cidade.page.tsx
│ ├── index.page.tsx
│ ├── _document.page.tsx
│ └── busca
│ │ ├── index.page.tsx
│ │ └── styles.module.scss
├── utils
│ └── mask.ts
├── data
│ ├── cities
│ │ ├── rr.json
│ │ ├── ap.json
│ │ ├── ac.json
│ │ ├── index.ts
│ │ ├── ro.json
│ │ ├── am.json
│ │ ├── se.json
│ │ ├── es.json
│ │ ├── ms.json
│ │ ├── rj.json
│ │ ├── al.json
│ │ └── to.json
│ ├── static-paths-candidate.json
│ ├── partidos.ts
│ └── mock-candidato.json
└── styles
│ ├── home.module.scss
│ └── globals.scss
├── public
├── logo.png
├── favicon.png
├── icons
│ ├── DC.png
│ ├── PL.png
│ ├── PP.png
│ ├── PT.png
│ ├── PV.png
│ ├── UP.png
│ ├── AGIR.png
│ ├── MDB.png
│ ├── NOVO.png
│ ├── PCB.png
│ ├── PCDOB.png
│ ├── PCO.png
│ ├── PDT.png
│ ├── PMB.png
│ ├── PODE.png
│ ├── PRD.png
│ ├── PRTB.png
│ ├── PSB.png
│ ├── PSD.png
│ ├── PSDB.png
│ ├── PSOL.png
│ ├── PSTU.png
│ ├── REDE.png
│ ├── UNIAO.png
│ ├── AVANTE.png
│ ├── CIDADANIA.png
│ ├── MOBILIZA.png
│ ├── REPUBLICANOS.png
│ └── SOLIDARIEDADE.png
├── cover-seo.png
├── google-news.png
├── favicon-32x32.png
├── flags
│ ├── flag-ac.png
│ ├── flag-al.jpg
│ ├── flag-am.jpg
│ ├── flag-ap.jpg
│ ├── flag-ba.jpg
│ ├── flag-ce.jpg
│ ├── flag-es.jpg
│ ├── flag-go.jpg
│ ├── flag-ma.jpg
│ ├── flag-mg.jpg
│ ├── flag-ms.jpg
│ ├── flag-mt.jpg
│ ├── flag-pa.jpg
│ ├── flag-pb.jpg
│ ├── flag-pe.jpg
│ ├── flag-pi.jpg
│ ├── flag-pr.jpg
│ ├── flag-rj.jpg
│ ├── flag-rn.jpg
│ ├── flag-ro.jpg
│ ├── flag-rr.jpg
│ ├── flag-rs.jpg
│ ├── flag-sc.jpg
│ ├── flag-se.jpg
│ ├── flag-sp.jpg
│ └── flag-to.jpg
├── favicon-180x180.png
├── favicon-192x192.png
├── robots.txt
└── sitemap.xml
├── .github
└── preview.png
├── next-sitemap.config.js
├── prettier.config.js
├── .editorconfig
├── next-env.d.ts
├── next.config.js
├── .gitignore
├── tsconfig.json
├── .eslintrc.json
├── package.json
└── README.md
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .next
3 | /*.js
--------------------------------------------------------------------------------
/src/hooks/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './useCandidates'
2 |
--------------------------------------------------------------------------------
/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/logo.png
--------------------------------------------------------------------------------
/src/types/city.d.ts:
--------------------------------------------------------------------------------
1 | export interface City {
2 | nome: string
3 | codigo: string
4 | }
5 |
--------------------------------------------------------------------------------
/.github/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/.github/preview.png
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/favicon.png
--------------------------------------------------------------------------------
/public/icons/DC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/DC.png
--------------------------------------------------------------------------------
/public/icons/PL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PL.png
--------------------------------------------------------------------------------
/public/icons/PP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PP.png
--------------------------------------------------------------------------------
/public/icons/PT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PT.png
--------------------------------------------------------------------------------
/public/icons/PV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PV.png
--------------------------------------------------------------------------------
/public/icons/UP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/UP.png
--------------------------------------------------------------------------------
/public/cover-seo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/cover-seo.png
--------------------------------------------------------------------------------
/public/google-news.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/google-news.png
--------------------------------------------------------------------------------
/public/icons/AGIR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/AGIR.png
--------------------------------------------------------------------------------
/public/icons/MDB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/MDB.png
--------------------------------------------------------------------------------
/public/icons/NOVO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/NOVO.png
--------------------------------------------------------------------------------
/public/icons/PCB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PCB.png
--------------------------------------------------------------------------------
/public/icons/PCDOB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PCDOB.png
--------------------------------------------------------------------------------
/public/icons/PCO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PCO.png
--------------------------------------------------------------------------------
/public/icons/PDT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PDT.png
--------------------------------------------------------------------------------
/public/icons/PMB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PMB.png
--------------------------------------------------------------------------------
/public/icons/PODE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PODE.png
--------------------------------------------------------------------------------
/public/icons/PRD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PRD.png
--------------------------------------------------------------------------------
/public/icons/PRTB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PRTB.png
--------------------------------------------------------------------------------
/public/icons/PSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PSB.png
--------------------------------------------------------------------------------
/public/icons/PSD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PSD.png
--------------------------------------------------------------------------------
/public/icons/PSDB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PSDB.png
--------------------------------------------------------------------------------
/public/icons/PSOL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PSOL.png
--------------------------------------------------------------------------------
/public/icons/PSTU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/PSTU.png
--------------------------------------------------------------------------------
/public/icons/REDE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/REDE.png
--------------------------------------------------------------------------------
/public/icons/UNIAO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/UNIAO.png
--------------------------------------------------------------------------------
/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/favicon-32x32.png
--------------------------------------------------------------------------------
/public/flags/flag-ac.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-ac.png
--------------------------------------------------------------------------------
/public/flags/flag-al.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-al.jpg
--------------------------------------------------------------------------------
/public/flags/flag-am.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-am.jpg
--------------------------------------------------------------------------------
/public/flags/flag-ap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-ap.jpg
--------------------------------------------------------------------------------
/public/flags/flag-ba.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-ba.jpg
--------------------------------------------------------------------------------
/public/flags/flag-ce.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-ce.jpg
--------------------------------------------------------------------------------
/public/flags/flag-es.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-es.jpg
--------------------------------------------------------------------------------
/public/flags/flag-go.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-go.jpg
--------------------------------------------------------------------------------
/public/flags/flag-ma.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-ma.jpg
--------------------------------------------------------------------------------
/public/flags/flag-mg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-mg.jpg
--------------------------------------------------------------------------------
/public/flags/flag-ms.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-ms.jpg
--------------------------------------------------------------------------------
/public/flags/flag-mt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-mt.jpg
--------------------------------------------------------------------------------
/public/flags/flag-pa.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-pa.jpg
--------------------------------------------------------------------------------
/public/flags/flag-pb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-pb.jpg
--------------------------------------------------------------------------------
/public/flags/flag-pe.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-pe.jpg
--------------------------------------------------------------------------------
/public/flags/flag-pi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-pi.jpg
--------------------------------------------------------------------------------
/public/flags/flag-pr.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-pr.jpg
--------------------------------------------------------------------------------
/public/flags/flag-rj.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-rj.jpg
--------------------------------------------------------------------------------
/public/flags/flag-rn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-rn.jpg
--------------------------------------------------------------------------------
/public/flags/flag-ro.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-ro.jpg
--------------------------------------------------------------------------------
/public/flags/flag-rr.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-rr.jpg
--------------------------------------------------------------------------------
/public/flags/flag-rs.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-rs.jpg
--------------------------------------------------------------------------------
/public/flags/flag-sc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-sc.jpg
--------------------------------------------------------------------------------
/public/flags/flag-se.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-se.jpg
--------------------------------------------------------------------------------
/public/flags/flag-sp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-sp.jpg
--------------------------------------------------------------------------------
/public/flags/flag-to.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/flags/flag-to.jpg
--------------------------------------------------------------------------------
/public/icons/AVANTE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/AVANTE.png
--------------------------------------------------------------------------------
/public/favicon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/favicon-180x180.png
--------------------------------------------------------------------------------
/public/favicon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/favicon-192x192.png
--------------------------------------------------------------------------------
/public/icons/CIDADANIA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/CIDADANIA.png
--------------------------------------------------------------------------------
/public/icons/MOBILIZA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/MOBILIZA.png
--------------------------------------------------------------------------------
/public/icons/REPUBLICANOS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/REPUBLICANOS.png
--------------------------------------------------------------------------------
/next-sitemap.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | siteUrl: 'https://www.omeuvoto.com.br/',
3 | generateRobotsTxt: true
4 | }
--------------------------------------------------------------------------------
/public/icons/SOLIDARIEDADE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leovargasdev/o-meu-voto/HEAD/public/icons/SOLIDARIEDADE.png
--------------------------------------------------------------------------------
/src/services/index.ts:
--------------------------------------------------------------------------------
1 | export { serviceGetCandidate } from './get-candidate'
2 | export { serviceGetCandidates } from './get-candidates'
3 |
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | semi: false,
3 | singleQuote: true,
4 | arrowParens: 'avoid',
5 | trailingComma: 'none',
6 | endOfLine: 'auto'
7 | };
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # *
2 | User-agent: *
3 | Allow: /
4 |
5 | # Host
6 | Host: https://www.omeuvoto.com.br/
7 |
8 | # Sitemaps
9 | Sitemap: https://www.omeuvoto.com.br/sitemap.xml
10 |
--------------------------------------------------------------------------------
/src/lib/api.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 |
3 | const api = axios.create({
4 | baseURL: 'https://divulgacandcontas.tse.jus.br/divulga/rest/v1/candidatura'
5 | })
6 |
7 | export default api
8 |
--------------------------------------------------------------------------------
/src/components/index.tsx:
--------------------------------------------------------------------------------
1 | export { Layout } from './Layout'
2 | export { Footer } from './Footer'
3 | export { MapBrazil } from './MapBrazil'
4 | export { SEO } from './SEO'
5 | export * from './SVG'
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | charset = utf-8
7 | end_of_line = lf
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
--------------------------------------------------------------------------------
/public/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | https://www.omeuvoto.com.br/sitemap-0.xml
4 |
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/src/components/SVG/index.tsx:
--------------------------------------------------------------------------------
1 | export { default as EmptyStateCandidate } from './empty-state-candidate'
2 | export { default as EmptyStateLocation } from './empty-state-location'
3 | export { default as EmptyStateService } from './empty-state-service'
4 |
--------------------------------------------------------------------------------
/src/lib/react-query.ts:
--------------------------------------------------------------------------------
1 | import { QueryClient } from '@tanstack/react-query'
2 |
3 | export const queryClient = new QueryClient({
4 | defaultOptions: {
5 | queries: {
6 | refetchOnWindowFocus: false,
7 | staleTime: Infinity
8 | }
9 | }
10 | })
11 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | swcMinify: true,
5 | pageExtensions: ['page.tsx', 'ts'],
6 | experimental: {
7 | optimizePackageImports: ['@phosphor-icons/react'],
8 | },
9 | }
10 |
11 | module.exports = nextConfig
12 |
--------------------------------------------------------------------------------
/src/types/index.d.ts:
--------------------------------------------------------------------------------
1 | export * from './candidate'
2 | export * from './city'
3 |
4 | export interface Option {
5 | value: string
6 | label: string
7 | }
8 |
9 | export type TypeLink =
10 | | 'default'
11 | | 'youtube'
12 | | 'x'
13 | | 'facebook'
14 | | 'instagram'
15 | | 'threads'
16 | | 'telegram'
17 | | 'linkedin'
18 | | 'tiktok'
19 |
20 | export interface SocialLink {
21 | type: TypeLink
22 | url: string
23 | }
24 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/News/styles.module.scss:
--------------------------------------------------------------------------------
1 | .googlenews {
2 | display: flex;
3 | align-items: center;
4 | column-gap: 6px;
5 |
6 | img {
7 | width: 20px;
8 | height: auto;
9 | }
10 |
11 | color: var(--text);
12 |
13 | border-radius: 20px;
14 | padding: 7px 18px 7px 12px;
15 | background: rgba(0,0,0,0.05);
16 |
17 | align-self: flex-start;
18 |
19 | @media(max-width: 650px) {
20 | img {
21 | width: 16px;
22 | }
23 |
24 | font-size: 12px;
25 | padding: 6px 12px;
26 | }
27 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
36 | yarn.lock
37 |
--------------------------------------------------------------------------------
/src/components/Footer/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | margin-top: auto;
3 | padding: 32px 24px 12px;
4 |
5 | display: flex;
6 | align-items: center;
7 | justify-content: space-between;
8 |
9 | font-size: 13px;
10 |
11 | width: 100%;
12 | max-width: 1366px;
13 |
14 | p a {
15 | color: var(--blue);
16 |
17 | &:hover {
18 | cursor: pointer;
19 | text-decoration: underline;
20 | }
21 | }
22 |
23 | @media (max-width: 650px) {
24 | flex-direction: column;
25 | row-gap: 16px;
26 | text-align: center;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Share/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: flex-end;
5 |
6 | p {
7 | line-height: 1.6;
8 | color: var(--text-secondary);
9 | font-size: 13px;
10 | }
11 |
12 | > div {
13 | display: flex;
14 | align-items: center;
15 | column-gap: 4px;
16 | }
17 |
18 | @media(max-width: 650px) {
19 | p {
20 | width: 90px;
21 | font-size: 11px;
22 | text-align: right;
23 | }
24 |
25 | > div svg {
26 | width: 14px;
27 | height: auto;
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true,
17 | "baseUrl": "./src/"
18 | },
19 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
20 | "exclude": ["node_modules"]
21 | }
22 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Tags/styles.module.scss:
--------------------------------------------------------------------------------
1 | .tags {
2 | display: flex;
3 | flex-wrap: wrap;
4 | align-items: center;
5 | gap: 12px;
6 |
7 | > span, a {
8 | display: flex;
9 | align-items: center;
10 | column-gap: 8px;
11 |
12 | font-size: 17px;
13 | color: var(--text-secondary);
14 | text-transform: capitalize;
15 |
16 | border-radius: 20px;
17 | padding: 7px 18px 7px 12px;
18 | background: rgba(0,0,0,0.05);
19 | }
20 |
21 | a {
22 | color: var(--blue);
23 | }
24 |
25 | @media(max-width: 650px) {
26 | > span, a {
27 | font-size: 14px;
28 | padding: 6px 14px 6px 9px;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/pages/_app.page.tsx:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 | import { queryClient } from 'lib/react-query'
3 | import { QueryClientProvider } from '@tanstack/react-query'
4 |
5 | import 'styles/globals.scss'
6 |
7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
8 | function MyApp({ Component, pageProps }: any) {
9 | return (
10 |
11 |
12 |
16 |
17 |
18 |
19 | )
20 | }
21 |
22 | export default MyApp
23 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Breadcrumb/styles.module.scss:
--------------------------------------------------------------------------------
1 | .breadcrumb {
2 | display: flex;
3 | align-items: center;
4 | column-gap: 12px;
5 |
6 | a, > span {
7 | display: flex;
8 | align-items: center;
9 | column-gap: 4px;
10 |
11 | font-size: 14px;
12 | letter-spacing: -0.3px;
13 |
14 | p span {
15 | text-transform: capitalize;
16 | }
17 | }
18 |
19 | a {
20 | color: var(--blue);
21 |
22 | &:hover {
23 | cursor: pointer;
24 | text-decoration: underline;
25 | }
26 | }
27 |
28 | @media(max-width: 600px) {
29 | gap: 2px 6px;
30 | flex-wrap: wrap;
31 |
32 | a, > span {
33 | font-size: 12px;
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/components/Footer/index.tsx:
--------------------------------------------------------------------------------
1 | import styles from './styles.module.scss'
2 |
3 | export const Footer = () => (
4 |
28 | )
29 |
--------------------------------------------------------------------------------
/src/utils/mask.ts:
--------------------------------------------------------------------------------
1 | export const maskOnlyNumber = (value: string): string => {
2 | return value.replace(/(\D)/g, '')
3 | }
4 |
5 | export const maskNumber = (value: string): number => {
6 | if (!value) return 0
7 | return Number(maskOnlyNumber(value))
8 | }
9 |
10 | export const normalizeString = (str: string) => {
11 | return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
12 | }
13 |
14 | export const maskToParamsURL = (str: string) =>
15 | normalizeString(str).toLocaleLowerCase().replace(/ /g, '-')
16 |
17 | export const maskSigla = (value: string) => {
18 | return normalizeString(value).replace(/\s/g, '').toUpperCase()
19 | }
20 |
21 | export const capitalizeString = (str: string) => {
22 | return str.replace(/(^\w|\s\w)/g, m => m.toUpperCase())
23 | }
24 |
--------------------------------------------------------------------------------
/src/pages/nao-encontrado/candidato.page.tsx:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 | import Head from 'next/head'
3 | import { EmptyStateCandidate, Layout } from 'components'
4 |
5 | import styles from './styles.module.scss'
6 |
7 | const EmptyPage = () => {
8 | return (
9 |
10 |
11 | Falha ao carregar dados do candidato
12 |
13 |
14 |
15 |
16 |
17 |
18 |
Ops... falha ao carregar dados!
19 | Não foi possível localizar os dados do candidato!
20 |
21 |
22 |
página inicial
23 |
24 |
25 | )
26 | }
27 |
28 | export default EmptyPage
29 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/News/index.tsx:
--------------------------------------------------------------------------------
1 | import type { Candidate } from 'types/candidate'
2 |
3 | import styles from './styles.module.scss'
4 |
5 | export const News = (candidate: Candidate) => {
6 | const role = candidate.cargo.nome
7 | const name = candidate.nomeUrna.toLocaleLowerCase().replace(/ /g, '%20')
8 | const city = candidate.localCandidatura.replace(/ /g, '%20')
9 |
10 | const querySearch = `${name}%20cargo%20de%20${role}%20${city}&hl=pt-BR&gl=BR&ceid=BR%3Apt-419`
11 |
12 | return (
13 |
19 |
20 | Google News - Veja notícias sobre o candidato
21 |
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/src/pages/nao-encontrado/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | row-gap: 24px;
6 |
7 | margin-top: 5vh;
8 |
9 | svg {
10 | width: 280px;
11 | height: auto;
12 |
13 | opacity: 0.8;
14 | }
15 |
16 | h1, h2 {
17 | text-align: center;
18 | }
19 |
20 | h2 {
21 | margin-top: 12px;
22 |
23 | font-size: 22px;
24 | line-height: 1.4;
25 | font-weight: 500;
26 | color: var(--text-secondary);
27 | }
28 |
29 | a {
30 | margin-top: 8px;
31 |
32 | font-size: 18px;
33 | text-transform: uppercase;
34 | color: #fff;
35 | font-weight: 600;
36 |
37 | padding: 8px 32px;
38 | border-radius: 8px;
39 | background-color: var(--blue);
40 |
41 | transition: all 0.4s;
42 |
43 | &:hover {
44 | filter: brightness(0.92);
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/src/pages/nao-encontrado/cidade.page.tsx:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 | import Head from 'next/head'
3 | import { EmptyStateLocation, Layout } from 'components'
4 |
5 | import styles from './styles.module.scss'
6 |
7 | const EmptyPage = () => {
8 | return (
9 |
10 |
11 | Falha ao carregar dados do município
12 |
13 |
14 |
15 |
16 |
17 |
18 |
Ops... falha ao carregar dados!
19 |
20 | O serviço do TSE pode estar fora do ar ou
21 |
22 | não foi possível localizar os dados deste município!
23 |
24 |
25 |
26 |
página inicial
27 |
28 |
29 | )
30 | }
31 |
32 | export default EmptyPage
33 |
--------------------------------------------------------------------------------
/src/components/SEO/index.tsx:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 | import { useRouter } from 'next/router'
3 |
4 | interface SEOProps {
5 | title: string
6 | description?: string
7 | }
8 |
9 | export const SEO = ({ title, description = '' }: SEOProps) => {
10 | const { asPath } = useRouter()
11 | const url = 'https://omeuvoto.com.br' + asPath
12 |
13 | return (
14 |
15 |
16 |
17 | {title}
18 | {description && }
19 |
20 |
21 | {description && (
22 |
23 | )}
24 |
25 |
26 | {description && }
27 |
28 |
29 | )
30 | }
31 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es2021": true
5 | },
6 | "extends": [
7 | "standard",
8 | "eslint:recommended",
9 | "plugin:react/recommended",
10 | "plugin:@typescript-eslint/recommended"
11 | ],
12 | "parser": "@typescript-eslint/parser",
13 | "parserOptions": {
14 | "ecmaFeatures": {
15 | "jsx": true
16 | },
17 | "ecmaVersion": "latest",
18 | "sourceType": "module"
19 | },
20 | "plugins": [
21 | "react",
22 | "prettier",
23 | "@typescript-eslint"
24 | ],
25 | "rules": {
26 | "multiline-ternary": "off",
27 | "prettier/prettier": "error",
28 | "space-before-function-paren": "off",
29 | "react/prop-types": "off",
30 | "react/react-in-jsx-scope": "off",
31 | "@typescript-eslint/explicit-module-boundary-types": "off"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/components/Layout/index.tsx:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 | import { Footer } from 'components'
3 | import { useRouter } from 'next/router'
4 |
5 | import styles from './styles.module.scss'
6 |
7 | interface LayoutProps {
8 | title?: string | React.ReactNode
9 | children: React.ReactNode
10 | }
11 |
12 | export const Layout = ({ children, title = '' }: LayoutProps) => {
13 | const router = useRouter()
14 |
15 | return (
16 |
17 | {router.pathname !== '/' && (
18 |
19 |
20 |
21 |
22 |
23 |
24 | {title &&
{title} }
25 |
26 |
27 | )}
28 |
29 |
{children}
30 |
31 |
32 |
33 | )
34 | }
35 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/InfoPoliticalParty/styles.module.scss:
--------------------------------------------------------------------------------
1 | .content {
2 | display: flex;
3 | flex-wrap: wrap;
4 | gap: 24px 64px;
5 |
6 | > div {
7 | display: flex;
8 | flex-direction: column;
9 | row-gap: 4px;
10 |
11 | strong {
12 | font-size: 16px;
13 | }
14 |
15 | p, a {
16 | font-size: 18px;
17 | text-transform: capitalize;
18 | }
19 |
20 | a {
21 | color: var(--blue);
22 |
23 | &:hover {
24 | text-decoration: underline;
25 | }
26 | }
27 | }
28 |
29 | @media(max-width: 650px) {
30 | gap: 18px 32px;
31 |
32 | > div {
33 | strong {
34 | font-size: 14px;
35 | }
36 |
37 | p {
38 | font-size: 15px;
39 | }
40 | }
41 | }
42 | }
43 |
44 | .images {
45 | display: flex;
46 | align-items: center;
47 | column-gap: 8px;
48 |
49 | img {
50 | width: 28px;
51 | height: auto;
52 | }
53 | }
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Breadcrumb/index.tsx:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 | import type { Candidate } from 'types'
3 | import { useRouter } from 'next/router'
4 | import { CaretRight, City, IdentificationCard } from '@phosphor-icons/react'
5 |
6 | import styles from './styles.module.scss'
7 |
8 | export const Breadcrumb = (candidate: Candidate) => {
9 | const router = useRouter()
10 | const hostCity = router.asPath.split('/candidato/')[0]
11 |
12 | return (
13 |
14 |
Eleições 2024
15 |
16 |
17 |
18 |
19 |
20 |
21 | {candidate.localCandidatura}
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Candidato(a) {candidate.nomeUrna.toLocaleLowerCase()}
31 |
32 |
33 |
34 | )
35 | }
36 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidatos/components/Skeleton/index.tsx:
--------------------------------------------------------------------------------
1 | import { Aside } from '../Aside'
2 | import { BookmarkSimple } from '@phosphor-icons/react'
3 |
4 | import styles from './styles.module.scss'
5 |
6 | export const CandidatesSkeleton = () => (
7 |
8 |
9 |
10 |
11 |
12 | Cargo de Prefeito
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Cargo de Vereador
24 |
25 |
26 | {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map(item => (
27 |
28 | ))}
29 |
30 |
31 |
32 |
33 |
34 |
35 | )
36 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Tags/index.tsx:
--------------------------------------------------------------------------------
1 | import * as emoji from 'node-emoji'
2 | import { differenceInYears } from 'date-fns'
3 | import type { Candidate } from 'types/candidate'
4 |
5 | import styles from './styles.module.scss'
6 |
7 | export const Tags = (candidate: Candidate) => (
8 |
41 | )
42 |
--------------------------------------------------------------------------------
/src/data/cities/rr.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "03050",
4 | "label": "alto alegre"
5 | },
6 | {
7 | "value": "03042",
8 | "label": "amajari"
9 | },
10 | {
11 | "value": "03018",
12 | "label": "boa vista"
13 | },
14 | {
15 | "value": "03077",
16 | "label": "bonfim"
17 | },
18 | {
19 | "value": "03069",
20 | "label": "cantá"
21 | },
22 | {
23 | "value": "03034",
24 | "label": "caracaraí"
25 | },
26 | {
27 | "value": "03000",
28 | "label": "caroebe"
29 | },
30 | {
31 | "value": "03026",
32 | "label": "iracema"
33 | },
34 | {
35 | "value": "03093",
36 | "label": "mucajaí"
37 | },
38 | {
39 | "value": "03115",
40 | "label": "normandia"
41 | },
42 | {
43 | "value": "03123",
44 | "label": "pacaraima"
45 | },
46 | {
47 | "value": "03085",
48 | "label": "rorainópolis"
49 | },
50 | {
51 | "value": "03131",
52 | "label": "são joão da baliza"
53 | },
54 | {
55 | "value": "03158",
56 | "label": "são luiz"
57 | },
58 | {
59 | "value": "03107",
60 | "label": "uiramutã"
61 | }
62 | ]
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidatos/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | align-items: flex-start;
4 | column-gap: 32px;
5 |
6 | @media(max-width: 1400px) {
7 | padding: 0 24px;
8 | }
9 |
10 | @media(max-width: 1000px) {
11 | flex-direction: column-reverse;
12 | row-gap: 24px;
13 | }
14 |
15 | @media(max-width: 650px) {
16 | row-gap: 6px;
17 | padding: 0 16px;
18 |
19 | > aside {
20 | display: none;
21 | }
22 | }
23 | }
24 |
25 | .loading {
26 | display: flex;
27 | align-items: center;
28 | justify-content: center;
29 | position: fixed;
30 | inset: 0;
31 |
32 | span {
33 | display: block;
34 | position: relative;
35 |
36 | &::after {
37 | content: '';
38 | position: absolute;
39 | inset: 0;
40 | margin: auto;
41 | display: block;
42 | width: 64px;
43 | height: 64px;
44 | background: transparent;
45 |
46 | border-radius: 50%;
47 | border: 1px solid transparent;
48 | border-left-color: var(--blue);
49 |
50 | animation: rotation 1s linear infinite;
51 |
52 | @keyframes rotation {
53 | 0% {
54 | transform: rotate(0deg);
55 | }
56 | 100% {
57 | transform: rotate(360deg);
58 | }
59 | }
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidatos/components/Skeleton/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | align-items: flex-start;
4 | column-gap: 32px;
5 |
6 | .candidates {
7 | display: grid;
8 | grid-template-columns: 1fr 1fr;
9 | gap: 16px;
10 |
11 | span {
12 | height: 56px;
13 | background-color: #fff;
14 |
15 | padding: 12px 16px;
16 | border-radius: 4px;
17 | box-shadow: rgba(0, 0, 0, 0.1) 1px 1px 2.6px;
18 | }
19 | }
20 |
21 | @media(max-width: 1400px) {
22 | padding: 0 24px;
23 | }
24 |
25 | @media(max-width: 1000px) {
26 | > aside {
27 | display: none;
28 | }
29 | }
30 |
31 | @media(max-width: 650px) {
32 | padding: 0 16px;
33 |
34 | .candidates {
35 | grid-template-columns: 1fr;
36 |
37 | span:nth-child(n + 5) {
38 | display: none;
39 | }
40 | }
41 | }
42 | }
43 |
44 | .content {
45 | flex: 1;
46 |
47 | display: flex;
48 | flex-direction: column;
49 | row-gap: 24px;
50 |
51 | section {
52 | display: flex;
53 | flex-direction: column;
54 | row-gap: 16px;
55 |
56 | h2 {
57 | display: flex;
58 | align-items: center;
59 | column-gap: 6px;
60 |
61 | font-size: 22px;
62 | font-weight: 500;
63 |
64 | @media(max-width: 650px) {
65 | font-size: 20px;
66 | }
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/src/data/cities/ap.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "06017",
4 | "label": "amapá"
5 | },
6 | {
7 | "value": "06033",
8 | "label": "calçoene"
9 | },
10 | {
11 | "value": "06068",
12 | "label": "cutias"
13 | },
14 | {
15 | "value": "06114",
16 | "label": "ferreira gomes"
17 | },
18 | {
19 | "value": "06041",
20 | "label": "itaubal"
21 | },
22 | {
23 | "value": "06130",
24 | "label": "laranjal do jari"
25 | },
26 | {
27 | "value": "06050",
28 | "label": "macapá"
29 | },
30 | {
31 | "value": "06076",
32 | "label": "mazagão"
33 | },
34 | {
35 | "value": "06092",
36 | "label": "oiapoque"
37 | },
38 | {
39 | "value": "06084",
40 | "label": "pedra branca do amapari"
41 | },
42 | {
43 | "value": "06025",
44 | "label": "porto grande"
45 | },
46 | {
47 | "value": "06009",
48 | "label": "pracuúba"
49 | },
50 | {
51 | "value": "06157",
52 | "label": "santana"
53 | },
54 | {
55 | "value": "06106",
56 | "label": "serra do navio"
57 | },
58 | {
59 | "value": "06173",
60 | "label": "tartarugalzinho"
61 | },
62 | {
63 | "value": "06122",
64 | "label": "vitória do jari"
65 | }
66 | ]
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "app-eleicoes",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@phosphor-icons/react": "^2.0.13",
13 | "@tanstack/react-query": "^5.52.1",
14 | "axios": "^1.4.0",
15 | "classnames": "^2.3.2",
16 | "date-fns": "^2.30.0",
17 | "framer-motion": "^11.5.4",
18 | "next": "13.5.4",
19 | "next-share": "^0.27.0",
20 | "node-emoji": "^2.1.3",
21 | "react": "^18.2.0",
22 | "react-dom": "^18.2.0",
23 | "react-select": "^5.8.0",
24 | "sass": "^1.62.1"
25 | },
26 | "devDependencies": {
27 | "@types/node": "^20.2.5",
28 | "@types/react": "^18.2.7",
29 | "@types/react-dom": "^18.2.4",
30 | "@typescript-eslint/eslint-plugin": "^5.31.0",
31 | "@typescript-eslint/parser": "^5.31.0",
32 | "eslint": "^8.0.1",
33 | "eslint-config-next": "13.1.1",
34 | "eslint-config-prettier": "^8.5.0",
35 | "eslint-config-standard": "^17.0.0",
36 | "eslint-plugin-import": "^2.25.2",
37 | "eslint-plugin-n": "^15.0.0",
38 | "eslint-plugin-prettier": "^4.0.0",
39 | "eslint-plugin-promise": "^6.0.0",
40 | "eslint-plugin-react": "^7.30.0",
41 | "eslint-plugin-standard": "^5.0.0",
42 | "next-sitemap": "^4.2.3",
43 | "prettier": "^2.8.1",
44 | "typescript": "^5.0.4"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/services/get-candidates.ts:
--------------------------------------------------------------------------------
1 | import api from 'lib/api'
2 | import { maskSigla } from 'utils/mask'
3 | import { Candidate, CandidateSimple } from 'types'
4 |
5 | interface Response {
6 | candidatos: Candidate[]
7 | unidadeEleitoral: {
8 | nome: string
9 | sigla: string
10 | }
11 | }
12 |
13 | const loadCandidates = async (cityId: string, role: string) => {
14 | try {
15 | const route = `/listar/2024/${cityId}/2045202024/${role}/candidatos`
16 | const { data } = await api.get(route)
17 |
18 | return data.candidatos.reduce((acc, candidate) => {
19 | if (candidate.descricaoSituacao !== 'Indeferido') {
20 | acc.push({
21 | nomeCompleto: candidate.nomeCompleto.toLocaleLowerCase(),
22 | id: candidate.id,
23 | numero: candidate.numero,
24 | nomeUrna: candidate.nomeUrna,
25 | partidoSigla: maskSigla(candidate.partido.sigla)
26 | })
27 | }
28 |
29 | return acc
30 | }, [] as CandidateSimple[])
31 | } catch (err) {
32 | console.log(err)
33 | }
34 |
35 | return null
36 | }
37 |
38 | export const serviceGetCandidates = async (cityId: string) => {
39 | try {
40 | const mayor = await loadCandidates(cityId, '11')
41 |
42 | if (mayor) {
43 | const deputyMayor = await loadCandidates(cityId, '12')
44 | const councilor = await loadCandidates(cityId, '13')
45 | return { mayor, deputyMayor, councilor }
46 | }
47 | } catch (e) {
48 | console.log(e)
49 | }
50 |
51 | return null
52 | }
53 |
--------------------------------------------------------------------------------
/src/components/Layout/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 |
6 | min-height: 100vh;
7 |
8 | > main {
9 | width: 100%;
10 | max-width: 1366px;
11 | }
12 | }
13 |
14 | .header {
15 | width: 100%;
16 | background-color: #fff;
17 | box-shadow: var(--shadow-border);
18 |
19 | margin-bottom: 32px;
20 |
21 | @media(max-width: 650px) {
22 | margin-bottom: 16px;
23 | }
24 | }
25 |
26 | .header__content {
27 | width: 100%;
28 | max-width: 1366px;
29 | margin: 12px auto;
30 |
31 | display: flex;
32 | align-items: center;
33 |
34 | h1 {
35 | font-size: 30px;
36 |
37 | flex: 1;
38 | text-align: center;
39 | padding-right: 72px;
40 |
41 | span {
42 | color: var(--blue);
43 | text-transform: capitalize;
44 | }
45 | }
46 |
47 | a {
48 | margin: 0 auto;
49 |
50 | img {
51 | height: 50px;
52 | width: auto;
53 | }
54 | }
55 |
56 | @media(max-width: 1400px) {
57 | padding: 0 24px;
58 | }
59 |
60 | @media(max-width: 1000px) {
61 | flex-direction: row-reverse;
62 |
63 | h1 {
64 | display: flex;
65 | flex-wrap: wrap;
66 |
67 | column-gap: 8px;
68 | padding-right: 0;
69 |
70 | font-size: 26px;
71 | }
72 | }
73 |
74 | @media(max-width: 650px) {
75 | padding: 0 16px;
76 |
77 | h1 {
78 | font-size: 20px;
79 | line-height: 1.2;
80 | }
81 |
82 | a img {
83 | height: 44px;
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/src/types/candidate.d.ts:
--------------------------------------------------------------------------------
1 | interface File {
2 | codTipo: string
3 | url: string
4 | nome: string
5 | }
6 |
7 | interface Property {
8 | ordem: string
9 | descricaoDeTipoDeBem: string
10 | descricao: string
11 | valor: string
12 | }
13 |
14 | export interface CandidateSimple {
15 | nomeCompleto: string
16 | id: number
17 | numero: number
18 | nomeUrna: string
19 | partidoSigla: string
20 | }
21 |
22 | interface PreviousElection {
23 | id: string
24 | cargo: string
25 | nrAno: number
26 | local: string
27 | partido: string
28 | sgUe: string
29 | situacaoTotalizacao: string
30 | }
31 |
32 | export interface Candidate extends CandidateSimple {
33 | arquivos: File[]
34 | sites: string[]
35 | fotoUrl: string
36 | localCandidatura: string
37 | ufSuperiorCandidatura: string
38 | cargo: {
39 | nome: string
40 | }
41 | nomeMunicipioNascimento: string
42 | descricaoSituacao?: string
43 | sgUfNascimento: string
44 | dataDeNascimento: string
45 | grauInstrucao: string
46 | ocupacao: string
47 | emails: string[]
48 | cnpjcampanha: string
49 | bens: Property[]
50 | totalDeBens: number
51 | partido: {
52 | sigla: string
53 | nome: string
54 | }
55 | reelicao: {
56 | eleito: boolean
57 | proposta?: string
58 | }
59 | nomeColigacao: string
60 | composicaoColigacao: string
61 | eleicoesAnteriores: PreviousElection[]
62 | otherCandidate: {
63 | id: number
64 | nomeCompleto: string
65 | nomeUrna: string
66 | urlFoto: string
67 | } | null
68 | }
69 |
--------------------------------------------------------------------------------
/src/pages/index.page.tsx:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 | import { NextPage } from 'next'
3 | import { EmptyStateService, Footer, SEO } from 'components'
4 |
5 | import styles from '../styles/home.module.scss'
6 |
7 | const LoginPage: NextPage = () => {
8 | const serviceNotFound = false
9 |
10 | return (
11 |
12 |
16 |
17 |
18 |
19 | Veja a lista dos candidatos do seu município
20 |
21 | {serviceNotFound && (
22 |
23 |
24 |
25 |
26 |
27 | O dados do{' '}
28 |
33 | TSE
34 | {' '}
35 | não estão disponíveis no momento!
36 |
37 |
Desculpe o transtorno, tente novamente mais tarde!
38 |
39 |
40 | )}
41 |
42 |
43 | Iniciar busca
44 |
45 |
46 |
47 |
48 |
49 | )
50 | }
51 |
52 | export default LoginPage
53 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Share/index.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | FacebookShareButton,
3 | FacebookIcon,
4 | WhatsappShareButton,
5 | WhatsappIcon,
6 | LinkedinShareButton,
7 | LinkedinIcon,
8 | // TwitterShareButton,
9 | // TwitterIcon,
10 | EmailShareButton,
11 | EmailIcon,
12 | TelegramShareButton,
13 | TelegramIcon
14 | } from 'next-share'
15 | import { useRouter } from 'next/router'
16 |
17 | import styles from './styles.module.scss'
18 |
19 | export const ShareCandidate = () => {
20 | const { asPath } = useRouter()
21 | const url = 'https://omeuvoto.com.br' + asPath
22 |
23 | return (
24 |
25 |
Compartilhe em:
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | {/*
37 |
38 | */}
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | )
48 | }
49 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Properties/styles.module.scss:
--------------------------------------------------------------------------------
1 | .total {
2 | margin-left: auto;
3 |
4 | padding: 7px 16px;
5 | border-radius: 20px;
6 | background: rgba(0,0,0,0.05);
7 |
8 | font-size: 15px;
9 | font-weight: 500;
10 |
11 | @media(max-width: 650px) {
12 | font-size: 12px;
13 | padding: 7px 12px;
14 | }
15 | }
16 |
17 | .empty {
18 | font-size: 16px;
19 | color: var(--text-secondary);
20 | font-weight: 500;
21 | padding-left: 2px;
22 |
23 | margin-top: -6px;
24 | }
25 |
26 | .properties {
27 | display: grid;
28 | grid-template-columns: 1fr 1fr;
29 | gap: 16px;
30 |
31 | width: 100%;
32 |
33 | @media(max-width: 600px) {
34 | grid-template-columns: 1fr;
35 | }
36 | }
37 |
38 | .property {
39 | display: flex;
40 | align-items: center;
41 | column-gap: 12px;
42 |
43 | > span {
44 | width: 40px;
45 | height: 40px;
46 | border-radius: 8px;
47 | background: var(--background);
48 |
49 | display: flex;
50 | align-items: center;
51 | justify-content: center;
52 | }
53 |
54 | div {
55 | display: flex;
56 | flex-direction: column;
57 | flex: 1;
58 |
59 | strong {
60 | font-size: 15px;
61 |
62 | -webkit-line-clamp: 1;
63 | overflow: hidden;
64 | display: -webkit-box;
65 | -webkit-box-orient: vertical;
66 | }
67 |
68 | span {
69 | font-size: 17px;
70 | }
71 | }
72 |
73 | @media(max-width: 650px) {
74 | > span {
75 | width: 36px;
76 | height: 36px;
77 | }
78 |
79 | div {
80 | span, strong {
81 | font-size: 14px;
82 | }
83 | }
84 | }
85 | }
86 |
87 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Meu Voto 2024
2 |
3 | 
4 |
5 |
6 |
7 | 
8 | 
9 | 
10 | [](https://github.com/leovargasdev/o-meu-voto/commits/master)
11 | [](https://github.com/leovargasdev/o-meu-voto/issues)
12 |
13 |
14 |
15 | ## 💻 Projeto
16 |
17 | [O Meu voto](https://omeuvoto.com.br/) é uma plataforma focada em listar os candidatos das eleições municipais de 2024 no Brasil.
18 |
19 | O principal objetivo é promover a transparência e facilitar o acesso às informações públicas, garantindo que os eleitores possam tomar decisões informadas. Todos os dados utilizados nesse projeto estão disponíveis de forma pública no [site do TSE](https://divulgacandcontas.tse.jus.br/divulga/#/home).
20 |
21 | ## 🚀 Tecnologias
22 |
23 | - [NextJS](https://nextjs.org/)
24 | - [Sass](https://sass-lang.com/)
25 | - [TypeScript](https://www.typescriptlang.org/)
26 |
27 | ## 📥 Rodando localmente
28 |
29 | Clone o projeto
30 |
31 | ```bash
32 | git clone https://github.com/leovargasdev/o-meu-voto
33 | ```
34 |
35 | Entre no diretório do projeto
36 |
37 | ```bash
38 | cd o-meu-voto
39 | ```
40 |
41 | Instale as dependências
42 |
43 | ```bash
44 | yarn install
45 | ```
46 |
47 | Inicie o servidor
48 |
49 | ```bash
50 | yarn next
51 | ```
52 |
--------------------------------------------------------------------------------
/src/styles/home.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | width: 100%;
3 | height: 100vh;
4 |
5 | display: flex;
6 | flex-direction: column;
7 | align-items: center;
8 | }
9 |
10 | .content {
11 | flex: 1;
12 |
13 | display: flex;
14 | flex-direction: column;
15 |
16 | align-items: center;
17 | justify-content: center;
18 |
19 | img {
20 | width: 250px;
21 | height: auto;
22 | }
23 |
24 | h1 {
25 | text-align: center;
26 | max-width: 500px;
27 | width: 100%;
28 |
29 | margin: 40px 0 48px;
30 | }
31 |
32 | > a {
33 | font-size: 18px;
34 | text-transform: uppercase;
35 | color: #fff;
36 | font-weight: 600;
37 |
38 | padding: 8px 32px;
39 | border-radius: 8px;
40 | background-color: var(--blue);
41 |
42 | transition: all 0.4s;
43 |
44 | &[aria-disabled="true"] {
45 | filter: grayscale(0.8);
46 | opacity: 0.4;
47 | pointer-events: none;
48 | }
49 |
50 | &:hover {
51 | filter: brightness(0.92);
52 | }
53 | }
54 |
55 | @media(max-width: 600px) {
56 | margin-top: 8vh;
57 | padding: 0 32px;
58 |
59 | h1 {
60 | font-size: 24px;
61 | }
62 |
63 | > a {
64 | font-size: 18px;
65 |
66 | padding: 8px 32px;
67 | border-radius: 8px;
68 | }
69 | }
70 | }
71 |
72 | .alert {
73 | display: flex;
74 | align-items: center;
75 | column-gap: 24px;
76 |
77 | border-radius: 8px;
78 | padding: 12px 16px;
79 | border: 2px solid #beb200;
80 | background-color: rgba(250, 238, 11, 0.6);
81 |
82 | margin: -24px 0 32px;
83 |
84 | a {
85 | color: var(--text);
86 | text-decoration: underline;
87 | }
88 |
89 | svg {
90 | width: auto;
91 | height: 45px;
92 | }
93 | }
--------------------------------------------------------------------------------
/src/styles/globals.scss:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: border-box;
5 | }
6 |
7 | :root {
8 | --text: #1d1d1f;
9 | --text-secondary: #6e6e73;
10 |
11 | --blue: #007aff;
12 | --green: #519548;
13 | --background: #f5f5f7;
14 |
15 | --shadow: 2px 4px 12px #00000014;
16 | --shadow-border: rgba(0, 0, 0, 0.03) 0px 0px 0px 1px;
17 | }
18 |
19 | body {
20 | background-color: var(--background);
21 | }
22 |
23 | body, button, textarea, input {
24 | font: 400 1rem 'Open Sans', sans-serif;
25 | }
26 |
27 | a {
28 | text-decoration: none;
29 | }
30 |
31 | fieldset {
32 | border: 0;
33 | }
34 |
35 | h1, h2, h3, h4, h5, h6, b, strong {
36 | color: var(--text);
37 | }
38 |
39 | button {
40 | border: 0;
41 | transition: all 0.4s;
42 |
43 | &:hover {
44 | cursor: pointer;
45 | }
46 | }
47 |
48 | .card {
49 | overflow: hidden;
50 | padding: 24px 32px;
51 | background-color: #fff;
52 | border-radius: 12px;
53 | box-shadow: var(--shadow);
54 |
55 | @media(max-width: 650px) {
56 | padding: 16px;
57 | }
58 | }
59 |
60 | // Select
61 | div[role="option"] {
62 | text-transform: capitalize;
63 | }
64 |
65 | .skeleton {
66 | border-radius: 4px;
67 | background-color: #f1f1f1;
68 |
69 | background-image: linear-gradient(90deg, rgba(#fff, 0), rgba(#fff, 0.5),rgba(#fff, 0));
70 | background-size: 40px 100%;
71 | background-repeat: no-repeat;
72 | background-position: left -40px top 0;
73 | animation: animation-skeleton 1.2s ease infinite;
74 |
75 | &.silver {
76 | background-image: linear-gradient(90deg, rgba(#eee, 0), rgba(#eee, 0.5),rgba(#eee, 0));
77 | }
78 | }
79 |
80 | @keyframes animation-skeleton {
81 | to {
82 | background-position: right -40px top 0;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/data/cities/ac.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "01120",
4 | "label": "acrelândia"
5 | },
6 | {
7 | "value": "01570",
8 | "label": "assis brasil"
9 | },
10 | {
11 | "value": "01058",
12 | "label": "brasiléia"
13 | },
14 | {
15 | "value": "01007",
16 | "label": "bujari"
17 | },
18 | {
19 | "value": "01015",
20 | "label": "capixaba"
21 | },
22 | {
23 | "value": "01074",
24 | "label": "cruzeiro do sul"
25 | },
26 | {
27 | "value": "01112",
28 | "label": "epitaciolândia"
29 | },
30 | {
31 | "value": "01139",
32 | "label": "feijó"
33 | },
34 | {
35 | "value": "01104",
36 | "label": "jordão"
37 | },
38 | {
39 | "value": "01090",
40 | "label": "mâncio lima"
41 | },
42 | {
43 | "value": "01554",
44 | "label": "manoel urbano"
45 | },
46 | {
47 | "value": "01040",
48 | "label": "marechal thaumaturgo"
49 | },
50 | {
51 | "value": "01511",
52 | "label": "plácido de castro"
53 | },
54 | {
55 | "value": "01023",
56 | "label": "porto acre"
57 | },
58 | {
59 | "value": "01066",
60 | "label": "porto walter"
61 | },
62 | {
63 | "value": "01392",
64 | "label": "rio branco"
65 | },
66 | {
67 | "value": "01082",
68 | "label": "rodrigues alves"
69 | },
70 | {
71 | "value": "01031",
72 | "label": "santa rosa do purus"
73 | },
74 | {
75 | "value": "01457",
76 | "label": "sena madureira"
77 | },
78 | {
79 | "value": "01538",
80 | "label": "senador guiomard"
81 | },
82 | {
83 | "value": "01473",
84 | "label": "tarauacá"
85 | },
86 | {
87 | "value": "01490",
88 | "label": "xapuri"
89 | }
90 | ]
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/PreviousElections/index.tsx:
--------------------------------------------------------------------------------
1 | import { Archive } from '@phosphor-icons/react'
2 | import type { Candidate } from 'types/candidate'
3 |
4 | import styles from './styles.module.scss'
5 |
6 | export const PreviousElections = ({ eleicoesAnteriores }: Candidate) => {
7 | const data = eleicoesAnteriores.filter(
8 | e => e.situacaoTotalizacao !== 'Concorrendo'
9 | )
10 |
11 | return (
12 |
13 |
14 |
15 | Eleições anteriores
16 |
17 |
18 | {data.length === 0 ? (
19 |
Não há dados registrados!
20 | ) : (
21 |
22 | {data.map(item => (
23 |
24 |
25 |
26 | {item.cargo} - {item.local.toLocaleLowerCase()}
27 |
28 |
29 |
Em {item.nrAno}
30 |
31 |
32 | {item.situacaoTotalizacao === 'Eleito por QP' && (
33 |
Eleito por legenda
34 | )}
35 | {item.situacaoTotalizacao === 'Suplente' && (
36 |
Suplente
37 | )}
38 | {item.situacaoTotalizacao === 'Eleito por média' && (
39 |
Eleito por média
40 | )}
41 | {item.situacaoTotalizacao === 'Não eleito' && (
42 |
Não eleito
43 | )}
44 | {['2º turno', 'Eleito'].includes(item.situacaoTotalizacao) && (
45 |
Eleito
46 | )}
47 |
48 | ))}
49 |
50 | )}
51 |
52 | )
53 | }
54 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidatos/components/FilterMobile/index.tsx:
--------------------------------------------------------------------------------
1 | import { Aside } from '../Aside'
2 | import { useEffect, useState } from 'react'
3 | import { motion, Variants } from 'framer-motion'
4 |
5 | import styles from './styles.module.scss'
6 | import { useCandidates } from 'hooks'
7 |
8 | export const container: Variants = {
9 | open: {
10 | clipPath: 'circle(2000px at 92vw 0px)',
11 | transition: {
12 | type: 'spring',
13 | stiffness: 20,
14 | restDelta: 2
15 | }
16 | },
17 | closed: {
18 | clipPath: 'circle(0px at 92vw 0px)',
19 | transition: {
20 | delay: 0.3,
21 | type: 'spring',
22 | stiffness: 400,
23 | damping: 40
24 | }
25 | }
26 | }
27 |
28 | export const FilterMobile = () => {
29 | const { candidates } = useCandidates()
30 | const [enabled, setEnabled] = useState(false)
31 |
32 | const toggleFilterMobile = () => {
33 | setEnabled(state => {
34 | document.body.style.overflow = state ? 'auto' : 'hidden'
35 | !state && window.scrollTo({ top: 0, behavior: 'smooth' })
36 | return !state
37 | })
38 | }
39 |
40 | useEffect(() => {
41 | if (enabled) toggleFilterMobile()
42 | }, [candidates])
43 |
44 | return (
45 |
46 |
51 | Filtros
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
66 |
71 |
72 |
73 | )
74 | }
75 |
--------------------------------------------------------------------------------
/src/data/static-paths-candidate.json:
--------------------------------------------------------------------------------
1 | [
2 | { "params": { "state": "sc", "city": "80810-chapeco" } },
3 | { "params": { "state": "sc", "city": "81051-florianopolis" } },
4 | { "params": { "state": "sc", "city": "80470-blumenau" } },
5 | { "params": { "state": "sc", "city": "81795-joinville" } },
6 | { "params": { "state": "sc", "city": "80896-criciuma" } },
7 | { "params": { "state": "sc", "city": "80390-balneario-camboriu" } },
8 | { "params": { "state": "rs", "city": "88013-porto-alegre" } },
9 | { "params": { "state": "rs", "city": "85995-caxias-do-sul" } },
10 | { "params": { "state": "rs", "city": "87718-novo-hamburgo" } },
11 | { "params": { "state": "rs", "city": "88412-santa-maria" } },
12 | { "params": { "state": "rs", "city": "87912-pelotas" } },
13 | { "params": { "state": "rs", "city": "89630-viamao" } },
14 | { "params": { "state": "pr", "city": "75353-curitiba" } },
15 | { "params": { "state": "pr", "city": "76910-maringa" } },
16 | { "params": { "state": "pr", "city": "77771-ponta-grossa" } },
17 | { "params": { "state": "pr", "city": "75639-foz-do-iguacu" } },
18 | { "params": { "state": "pr", "city": "74934-cascavel" } },
19 | { "params": { "state": "sp", "city": "64777-guarulhos" } },
20 | { "params": { "state": "sp", "city": "67890-osasco" } },
21 | { "params": { "state": "sp", "city": "71455-sorocaba" } },
22 | { "params": { "state": "ms", "city": "90514-campo-grande" } },
23 | { "params": { "state": "ms", "city": "90735-dourados" } },
24 | { "params": { "state": "ms", "city": "91650-tres-lagoas" } },
25 | { "params": { "state": "ms", "city": "90638-corumba" } },
26 | { "params": { "state": "ms", "city": "98035-costa-rica" } },
27 | { "params": { "state": "rj", "city": "58130-cabo-frio" } },
28 | { "params": { "state": "rj", "city": "58033-araruama" } },
29 | { "params": { "state": "rj", "city": "58653-niteroi" } },
30 | { "params": { "state": "rj", "city": "58696-nova-iguacu" } },
31 | { "params": { "state": "ba", "city": "38490-salvador" } },
32 | { "params": { "state": "ba", "city": "37710-palmeiras" } }
33 | ]
--------------------------------------------------------------------------------
/src/hooks/useCandidates.tsx:
--------------------------------------------------------------------------------
1 | import type { CandidateSimple } from 'types'
2 | import { createContext, useContext, useEffect, useState } from 'react'
3 |
4 | interface Filter {
5 | parties: string[]
6 | candidateName: string
7 | role: string
8 | }
9 |
10 | interface Candidates {
11 | mayor: CandidateSimple[]
12 | deputyMayor: CandidateSimple[]
13 | councilor: CandidateSimple[]
14 | }
15 |
16 | export interface CandidatesContextData {
17 | filter: Filter
18 | candidates: Candidates
19 | handleChangeFilter: (value: Partial) => void
20 | handleChangeFilterParties: (value: string) => void
21 | }
22 |
23 | interface CandidatesProviderProps {
24 | candidates: Candidates
25 | children: React.ReactNode
26 | }
27 |
28 | const CandidatesContext = createContext({} as CandidatesContextData)
29 |
30 | export function CandidatesProvider({
31 | candidates,
32 | children
33 | }: CandidatesProviderProps) {
34 | const [filter, setFilter] = useState({
35 | parties: [],
36 | candidateName: '',
37 | role: ''
38 | })
39 |
40 | const handleChangeFilter = (update: Partial) => {
41 | setFilter(state => ({ ...state, ...update }))
42 | }
43 |
44 | const handleChangeFilterParties = (partyId: string) => {
45 | if (filter.parties.includes(partyId)) {
46 | const parties = filter.parties.filter(p => p !== partyId)
47 | handleChangeFilter({ parties })
48 | return
49 | }
50 |
51 | handleChangeFilter({ parties: [...filter.parties, partyId] })
52 | }
53 |
54 | useEffect(() => {
55 | if (filter.parties.length > 0) {
56 | handleChangeFilter({ parties: [] })
57 | }
58 | }, [candidates])
59 |
60 | return (
61 |
69 | {children}
70 |
71 | )
72 | }
73 |
74 | export function useCandidates() {
75 | const context = useContext(CandidatesContext)
76 | return context
77 | }
78 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/InfoPoliticalParty/index.tsx:
--------------------------------------------------------------------------------
1 | import { maskSigla } from 'utils/mask'
2 | import listParties from 'data/partidos'
3 | import { Users } from '@phosphor-icons/react'
4 | import type { Candidate } from 'types/candidate'
5 |
6 | import styles from './styles.module.scss'
7 |
8 | type KeyParty = keyof typeof listParties
9 |
10 | const getGroupParties = (value: string) => {
11 | const parties = value.split(' / ')
12 |
13 | return parties.reduce((acc, party) => {
14 | const key = maskSigla(party).toLocaleLowerCase()
15 |
16 | const data = listParties[key as KeyParty]
17 | data?.name && acc.push(data)
18 |
19 | return acc
20 | }, [] as any[])
21 | }
22 |
23 | export const InfoPoliticalParty = (candidate: Candidate) => {
24 | const groupParties = getGroupParties(candidate.composicaoColigacao)
25 |
26 | const sigla = candidate.partidoSigla.toLocaleLowerCase() as KeyParty
27 | const linkParty = listParties[sigla]?.link
28 |
29 | return (
30 |
31 |
32 |
33 | Partido político
34 |
35 |
36 |
37 |
43 |
44 |
Coligação
45 |
{candidate.nomeColigacao.toLocaleLowerCase()}
46 |
47 | {groupParties.length > 1 && (
48 |
49 |
Composição da coligação
50 |
51 | {groupParties.map(party => (
52 |
59 | ))}
60 |
61 |
62 | )}
63 |
64 |
65 | )
66 | }
67 |
--------------------------------------------------------------------------------
/src/components/SVG/empty-state-service.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function Icon() {
4 | return (
5 |
12 |
18 |
19 | )
20 | }
21 |
22 | export default React.memo(Icon)
23 |
--------------------------------------------------------------------------------
/src/pages/_document.page.tsx:
--------------------------------------------------------------------------------
1 | import Document, { Html, Head, Main, NextScript } from 'next/document'
2 | import Script from 'next/script'
3 |
4 | export default class MyDocument extends Document {
5 | render() {
6 | return (
7 |
8 |
9 |
10 |
11 |
17 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
36 |
37 |
38 |
42 |
43 |
47 |
48 |
52 |
53 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | )
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/PreviousElections/styles.module.scss:
--------------------------------------------------------------------------------
1 | .empty {
2 | font-size: 16px;
3 | color: var(--text-secondary);
4 | font-weight: 500;
5 | padding-left: 2px;
6 |
7 | margin-top: -6px;
8 | }
9 |
10 | .list {
11 | display: flex;
12 | flex-direction: column;
13 | width: 100%;
14 | }
15 |
16 | .item {
17 | margin-left: 8px;
18 | padding-left: 24px;
19 | padding-bottom: 32px;
20 |
21 | position: relative;
22 |
23 | border-left: 1px solid rgba(0, 0, 0, 0.2);
24 |
25 | &::before, &::after {
26 | content: '';
27 | width: 10px;
28 |
29 | position: absolute;
30 | left: -9px;
31 | }
32 |
33 | &::before {
34 | height: 10px;
35 | border: 4px solid #fff;
36 | border-radius: 100%;
37 | background: var(--text-secondary);
38 |
39 | top: 4px;
40 | }
41 |
42 | &::after {
43 | height: 6px;
44 | background: #fff;
45 | top: -2px;
46 | }
47 |
48 | display: flex;
49 | align-items: center;
50 | column-gap: 16px;
51 |
52 | img {
53 | width: 40px;
54 | height: auto;
55 | }
56 |
57 | div {
58 | display: flex;
59 | flex-direction: column;
60 |
61 | strong {
62 | font-size: 18px;
63 | font-weight: 600;
64 |
65 | span {
66 | text-transform: capitalize;
67 | }
68 | }
69 |
70 | p {
71 | font-size: 15px;
72 | color: var(--text-secondary);
73 | }
74 | }
75 |
76 | > span {
77 | margin-left: auto;
78 | padding: 4px 10px;
79 | border-radius: 6px;
80 | color: #fff;
81 | font-size: 14px;
82 |
83 | &.success {
84 | background-color: rgba(81, 149, 72, 0.8);
85 | }
86 |
87 | &.fail {
88 | background-color: rgba(237, 28, 37, 0.8);
89 | }
90 |
91 | &.partial {
92 | background-color: rgba(145, 149, 72, 0.8);
93 | }
94 | }
95 |
96 | @media(max-width: 650px) {
97 | margin-left: 8px;
98 | padding-left: 16px;
99 | padding-bottom: 24px;
100 |
101 | flex-direction: column-reverse;
102 | align-items: flex-start;
103 | row-gap: 6px;
104 |
105 | div {
106 | strong {
107 | font-size: 15px;
108 | }
109 |
110 | p {
111 | font-size: 14px;
112 | }
113 | }
114 |
115 | > span {
116 | margin-left: 0;
117 | padding: 4px 8px;
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Skeleton/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | width: 100%;
3 | display: flex;
4 | align-items: flex-start;
5 | column-gap: 32px;
6 |
7 | @media(max-width: 1400px) {
8 | padding: 0 24px;
9 | }
10 |
11 | @media(max-width: 768px) {
12 | flex-direction: column;
13 | row-gap: 24px;
14 | }
15 |
16 | @media(max-width: 650px) {
17 | padding: 0 16px;
18 | }
19 | }
20 |
21 | .profile {
22 | display: flex;
23 | flex-direction: column;
24 | align-items: center;
25 | row-gap: 12px;
26 |
27 | padding: 32px;
28 |
29 | text-align: center;
30 |
31 | .profile__image {
32 | width: 140px;
33 | height: 180px;
34 | border-radius: 20px;
35 | border: 4px solid #fff;
36 | background-color: var(--background);
37 | }
38 |
39 | .code {
40 | display: flex;
41 | column-gap: 4px;
42 |
43 | span {
44 | background: var(--green);
45 | padding: 3px 6px;
46 | border-radius: 2px;
47 | color: #fff;
48 | font-size: 24px;
49 | }
50 | }
51 |
52 | .title {
53 | width: 200px;
54 | height: 38px;
55 | }
56 |
57 | .description {
58 | display: flex;
59 | flex-direction: column;
60 | row-gap: 8px;
61 |
62 | span {
63 | width: 250px;
64 | height: 24px;
65 | }
66 | }
67 |
68 | @media(max-width: 768px) {
69 | width: 100%;
70 | }
71 |
72 | @media(max-width: 650px) {
73 | padding: 16px;
74 |
75 | .flag {
76 | display: none;
77 | }
78 |
79 | > div {
80 | margin-top: 0;
81 | }
82 | }
83 | }
84 |
85 | .cards {
86 | flex: 1;
87 | width: 100%;
88 |
89 | display: flex;
90 | flex-direction: column;
91 | row-gap: 32px;
92 |
93 | > div {
94 | display: flex;
95 | flex-direction: column;
96 | row-gap: 12px;
97 |
98 | h2 {
99 | display: flex;
100 | align-items: center;
101 | column-gap: 8px;
102 |
103 | font-size: 22px;
104 | font-weight: 600;
105 | margin-bottom: 8px;
106 | }
107 | }
108 | }
109 |
110 | .tags {
111 | display: flex;
112 | flex-wrap: wrap;
113 | gap: 12px;
114 |
115 | span {
116 | height: 37px;
117 | border-radius: 20px;
118 | }
119 |
120 | @media(max-width: 650px) {
121 | span {
122 | height: 30px;
123 | }
124 | }
125 | }
126 |
127 | .property {
128 | height: 42px;
129 | width: 100%;
130 | }
131 |
132 | .election {
133 | height: 36px;
134 | width: 100%;
135 | }
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidatos/components/Candidates/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | flex: 1;
3 |
4 | display: flex;
5 | flex-direction: column;
6 | row-gap: 24px;
7 |
8 | @media(max-width: 1000px) {
9 | width: 100%;
10 | }
11 | }
12 |
13 | .section {
14 | display: flex;
15 | flex-direction: column;
16 | row-gap: 16px;
17 |
18 | width: 100%;
19 |
20 | h2 {
21 | display: flex;
22 | align-items: center;
23 | column-gap: 6px;
24 |
25 | font-size: 22px;
26 | font-weight: 500;
27 |
28 | @media(max-width: 768px) {
29 | font-size: 20px;
30 | }
31 | }
32 |
33 | .candidates {
34 | display: grid;
35 | grid-template-columns: 1fr 1fr;
36 | gap: 16px;
37 |
38 | @media(min-width: 1079px) {
39 | &:has(a:hover) a:not(:hover) {
40 | filter: grayscale(0.45) opacity(0.65);
41 | }
42 | }
43 |
44 | @media(max-width: 768px) {
45 | display: flex;
46 | flex-direction: column;
47 | }
48 | }
49 | }
50 |
51 | .candidate {
52 | display: flex;
53 | align-items: center;
54 | column-gap: 12px;
55 |
56 | padding: 12px 16px;
57 | border-radius: 4px;
58 | box-shadow: rgba(0, 0, 0, 0.1) 1px 1px 2.6px;
59 |
60 | transition: all 0.3s;
61 |
62 | .info {
63 | strong, p {
64 | line-height: 1;
65 | display: block;
66 | text-transform: capitalize;
67 | }
68 |
69 | strong {
70 | font-size: 16px;
71 | font-weight: 600;
72 | margin-bottom: 4px;
73 | }
74 |
75 | p {
76 | color: var(--text-secondary);
77 | font-size: 12px;
78 | }
79 | }
80 |
81 | .code {
82 | display: flex;
83 | column-gap: 4px;
84 |
85 | margin-left: auto;
86 |
87 | span {
88 | background: var(--green);
89 | padding: 3px 6px;
90 | border-radius: 2px;
91 | color: #fff;
92 | font-size: 18px;
93 | }
94 | }
95 |
96 | @media(max-width: 650px) {
97 | padding: 12px;
98 |
99 | .info strong {
100 | font-size: 15px;
101 | letter-spacing: -0.3px;
102 | }
103 |
104 | .code {
105 | column-gap: 3px;
106 |
107 | span {
108 | font-size: 16px;
109 | padding: 3px 5px;
110 | }
111 | }
112 | }
113 |
114 | @media(max-width: 370px) {
115 | padding: 10px;
116 |
117 | .info strong {
118 | font-size: 14px;
119 | }
120 |
121 | .code {
122 | span {
123 | font-size: 15px;
124 | padding: 3px 4px;
125 | }
126 | }
127 |
128 | }
129 | }
--------------------------------------------------------------------------------
/src/pages/busca/index.page.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import Select from 'react-select'
3 | import classNames from 'classnames'
4 | import { useRouter } from 'next/router'
5 |
6 | import type { Option } from 'types'
7 | import { MapBrazil, SEO } from 'components'
8 | import { maskToParamsURL } from 'utils/mask'
9 | import { citiesByState } from 'data/cities/'
10 |
11 | import styles from './styles.module.scss'
12 |
13 | interface QuestionProps {
14 | label: string
15 | enabled: boolean
16 | children: React.ReactNode
17 | }
18 |
19 | const Question = ({ label, enabled, children }: QuestionProps) => (
20 |
21 |
22 | {label}
23 | {children}
24 |
25 |
26 | )
27 |
28 | const SearchPage = () => {
29 | const router = useRouter()
30 | const [question, setQuestion] = useState(0)
31 | const [state, setState] = useState('')
32 |
33 | const handleQuestionUF = (value: string) => {
34 | setState(value)
35 | setQuestion(1)
36 | }
37 |
38 | const handleQuestionCity = (option: Option | null) => {
39 | if (option) {
40 | setQuestion(2)
41 |
42 | const cityPath = option.value + '-' + maskToParamsURL(option.label)
43 | router.push(`/${state}/${cityPath}/candidatos`)
44 | }
45 | }
46 |
47 | const cities = state ? citiesByState[state] : []
48 |
49 | return (
50 |
51 |
55 |
56 |
57 |
58 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
76 |
77 |
78 |
79 |
80 | )
81 | }
82 |
83 | export default SearchPage
84 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | flex-direction: column;
4 | row-gap: 20px;
5 |
6 | @media(max-width: 1400px) {
7 | padding: 0 24px;
8 | }
9 | }
10 |
11 | .head {
12 | display: flex;
13 | justify-content: space-between;
14 | align-items: flex-end;
15 |
16 | margin-top: -12px;
17 |
18 | @media(max-width: 650px) {
19 | margin-top: 0;
20 | }
21 | }
22 |
23 | .content {
24 | width: 100%;
25 | display: flex;
26 | align-items: flex-start;
27 | column-gap: 32px;
28 |
29 | @media(max-width: 1000px) {
30 | flex-direction: column;
31 | row-gap: 32px;
32 | }
33 |
34 | @media(max-width: 650px) {
35 | row-gap: 24px;
36 | }
37 | }
38 |
39 | .cards {
40 | flex: 1;
41 | width: 100%;
42 |
43 | display: flex;
44 | flex-direction: column;
45 | row-gap: 32px;
46 |
47 | > div > h2 {
48 | display: flex;
49 | align-items: center;
50 | flex-wrap: wrap;
51 | column-gap: 8px;
52 |
53 | font-size: 22px;
54 | font-weight: 600;
55 | margin-bottom: 20px;
56 | }
57 |
58 | @media(max-width: 650px) {
59 | row-gap: 24px;
60 |
61 | > div > h2 {
62 | font-size: 18px;
63 | gap: 6px;
64 | }
65 | }
66 | }
67 |
68 | .alert {
69 | display: flex;
70 | flex-direction: column;
71 | row-gap: 1px;
72 |
73 | padding: 14px;
74 | border-radius: 10px;
75 | background-color: #FFF3E0;
76 | border: 1px solid #FF9800;
77 | box-shadow: var(--shadow);
78 |
79 | margin-bottom: -4px;
80 |
81 | > div {
82 | display: flex;
83 | align-items: center;
84 | column-gap: 8px;
85 |
86 | line-height: 1.3;
87 | margin-bottom: 6px;
88 |
89 | strong, p, p b {
90 | color: #FF9800;
91 | }
92 |
93 | strong {
94 | font-size: 18px;
95 | font-weight: 600;
96 | }
97 |
98 | p b {
99 | font-weight: 600;
100 | text-transform: capitalize;
101 | }
102 | }
103 |
104 | a {
105 | color: #FF9800;
106 |
107 | text-decoration: underline;
108 | padding-left: 44px;
109 | }
110 |
111 | @media(max-width: 650px) {
112 | padding: 8px;
113 |
114 | div {
115 | column-gap: 6px;
116 | align-items: flex-start;
117 |
118 | svg {
119 | width: 22px;
120 | height: auto;
121 | padding-top: 2px;
122 | }
123 |
124 | strong, a {
125 | font-size: 14px;
126 | }
127 |
128 | p {
129 | font-size: 12px;
130 | }
131 | }
132 | }
133 | }
134 |
135 | .info {
136 | display: flex;
137 | flex-direction: column;
138 | row-gap: 12px;
139 | }
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidatos/components/FilterMobile/styles.module.scss:
--------------------------------------------------------------------------------
1 | .filter {
2 | display: none;
3 | justify-content: flex-end;
4 |
5 | width: 100%;
6 |
7 | > button {
8 | display: flex;
9 | align-items: center;
10 | column-gap: 12px;
11 |
12 | padding: 5px 8px;
13 | background: transparent;
14 | border-radius: 4px;
15 | border: 1px solid hsl(0, 0%, 80%);
16 |
17 | color: var(--text);
18 | // text-transform: uppercase;
19 |
20 | z-index: 3;
21 | }
22 |
23 | @media(max-width: 650px) {
24 | display: flex;
25 | }
26 | }
27 |
28 | .container {
29 | position: fixed;
30 | left: 0;
31 | right: 0;
32 | bottom: 0;
33 | height: calc(100svh - 94px);
34 |
35 | backdrop-filter: blur(3px);
36 | background: rgba(0, 0, 0, 0.15);
37 |
38 | z-index: 2;
39 |
40 | overflow: hidden;
41 | }
42 |
43 | .content {
44 | width: 90vw;
45 | height: 100%;
46 | margin-left: auto;
47 |
48 | padding: 32px 20px 24px 24px;
49 |
50 | background: var(--background);
51 |
52 | }
53 |
54 | .content2 {
55 | height: 100%;
56 | overflow: auto;
57 |
58 | padding-right: 4px;
59 | scrollbar-width: thin;
60 | scrollbar-color: #a1a4a7 transparent;
61 |
62 | &::-webkit-scrollbar {
63 | width: 4px;
64 | height: 4px;
65 | background: #d9d9d9;
66 | border-radius: 10px;
67 | }
68 |
69 | &::-webkit-scrollbar-thumb {
70 | background: #bebebe;
71 | border-radius: 10px;
72 | }
73 | }
74 |
75 | .hamburger {
76 | width: 20px;
77 | height: 14px;
78 | position: relative;
79 |
80 | transform: rotate(0deg);
81 | transition: .5s ease-in-out;
82 |
83 | z-index: 3;
84 |
85 | cursor: pointer;
86 |
87 | span {
88 | display: block;
89 | position: absolute;
90 | height: 2px;
91 | width: 100%;
92 | background: var(--text);
93 | border-radius: 2px;
94 | left: 0;
95 |
96 | transform: rotate(0deg);
97 | transition: .25s ease-in-out;
98 |
99 | &:nth-child(1) {
100 | top: 0px;
101 | }
102 |
103 | &:nth-child(2), &:nth-child(3) {
104 | top: 6px;
105 | }
106 |
107 | &:nth-child(4) {
108 | top: 12px;
109 | }
110 | }
111 |
112 | &[data-state="open"] {
113 | span:nth-child(1) {
114 | top: 6px;
115 | width: 0%;
116 | left: 50%;
117 | }
118 |
119 | span:nth-child(2) {
120 | transform: rotate(45deg);
121 | }
122 |
123 | span:nth-child(3) {
124 | transform: rotate(-45deg);
125 | }
126 |
127 | span:nth-child(4) {
128 | top: 6px;
129 | width: 0%;
130 | left: 50%;
131 | }
132 | }
133 | }
--------------------------------------------------------------------------------
/src/pages/busca/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | position: fixed;
3 | inset: 0;
4 |
5 | z-index: 2;
6 | overflow: hidden;
7 |
8 | > img {
9 | position: absolute;
10 | top: 20px;
11 | right: 24px;
12 | z-index: 10;
13 |
14 | width: 150px;
15 | height: auto;
16 |
17 | @media(max-width: 600px) {
18 | width: 95px;
19 | }
20 | }
21 | }
22 |
23 | .content {
24 | display: flex;
25 | width: 200vw;
26 | background-color: var(--background);
27 |
28 | transition: all 0.5s ease-in-out;
29 | }
30 |
31 | .carrousel__item {
32 | display: flex;
33 | align-items: center;
34 | justify-content: center;
35 |
36 | height: 100vh;
37 | width: 100vw;
38 |
39 | opacity: 0;
40 |
41 | transition: all 0.5s ease-in-out;
42 |
43 | &.enable {
44 | opacity: 1;
45 | }
46 | }
47 |
48 | .label {
49 | display: block;
50 |
51 | font-size: 28px;
52 | text-align: center;
53 | color: var(--text);
54 |
55 | margin-bottom: 32px;
56 |
57 | @media(max-width: 650px) {
58 | font-size: 20px;
59 | }
60 | }
61 |
62 | .map {
63 | svg {
64 | width: auto;
65 | height: 75vh;
66 | max-height: 800px;
67 | }
68 |
69 | svg g:hover path {
70 | cursor: pointer;
71 | fill: var(--blue);
72 | }
73 |
74 | @media(max-width: 600px) {
75 | svg {
76 | width: 110vw;
77 | height: auto;
78 | margin-left: 38px;
79 | }
80 | }
81 | }
82 |
83 | .cities {
84 | width: 450px;
85 |
86 | @media(max-width: 650px) {
87 | width: 80vw;
88 | margin-bottom: 120px;
89 | }
90 | }
91 |
92 | .roles {
93 | display: flex;
94 | flex-direction: column;
95 | align-items: center;
96 | row-gap: 32px;
97 |
98 | button {
99 | font-size: 1.25rem;
100 | font-weight: 500;
101 | letter-spacing: -0.03em;
102 | }
103 |
104 | > button {
105 | display: flex;
106 | align-items: center;
107 | column-gap: 4px;
108 |
109 | color: var(--blue);
110 | background: transparent;
111 | }
112 | }
113 |
114 | .buttons {
115 | display: flex;
116 | column-gap: 32px;
117 |
118 | button {
119 | width: 250px;
120 |
121 | padding: 0.5em 0;
122 | background-color: rgba(255, 255, 255, 0.5);
123 | box-shadow: 1px 1px 4px 1px rgba(0, 0, 0, 0.05);
124 |
125 | border-radius: 8px;
126 | border: 2px solid transparent;
127 |
128 | transition: all 0.3s ease;
129 |
130 | &:hover {
131 | cursor: pointer;
132 | color: var(--blue);
133 | border: 2px solid var(--blue);
134 | }
135 | }
136 |
137 | @media(max-width: 650px) {
138 | flex-direction: column;
139 | align-items: center;
140 | row-gap: 16px;
141 | }
142 | }
--------------------------------------------------------------------------------
/src/components/SVG/empty-state-candidate.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function Icon() {
4 | return (
5 |
12 |
20 |
26 |
27 | )
28 | }
29 |
30 | export default React.memo(Icon)
31 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Skeleton/index.tsx:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 | import classNames from 'classnames'
3 | import { Layout } from 'components'
4 | import { useParams } from 'next/navigation'
5 | import { capitalizeString } from 'utils/mask'
6 | import { Archive, Receipt } from '@phosphor-icons/react'
7 |
8 | import styles from './styles.module.scss'
9 |
10 | export const CandidateSkeleton = () => {
11 | const params = useParams()
12 |
13 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
14 | const [_, ...candidateName] = ((params?.id as string) || '-').split('-')
15 | const title = `Carregando candidato ${capitalizeString(
16 | candidateName.join(' ')
17 | )}`
18 |
19 | return (
20 |
21 |
22 | {title}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | 0
31 | 0
32 | 0
33 | 0
34 | 0
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | Patrimônio declarado
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | Eleições anteriores
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | )
81 | }
82 |
--------------------------------------------------------------------------------
/src/data/cities/index.ts:
--------------------------------------------------------------------------------
1 | import ac from './ac.json'
2 | import al from './al.json'
3 | import am from './am.json'
4 | import ap from './ap.json'
5 | import ba from './ba.json'
6 | import ce from './ce.json'
7 | import es from './es.json'
8 | import go from './go.json'
9 | import ma from './ma.json'
10 | import mg from './mg.json'
11 | import ms from './ms.json'
12 | import mt from './mt.json'
13 | import pa from './pa.json'
14 | import pb from './pb.json'
15 | import pe from './pe.json'
16 | import pi from './pi.json'
17 | import pr from './pr.json'
18 | import rj from './rj.json'
19 | import rn from './rn.json'
20 | import ro from './ro.json'
21 | import rr from './rr.json'
22 | import rs from './rs.json'
23 | import sc from './sc.json'
24 | import se from './se.json'
25 | import sp from './sp.json'
26 | import to from './to.json'
27 |
28 | import { Option } from 'types'
29 |
30 | export const states = [
31 | { label: 'Acre', value: 'ac' },
32 | { label: 'Alagoas', value: 'al' },
33 | { label: 'Amapá', value: 'ap' },
34 | { label: 'Amazonas', value: 'am' },
35 | { label: 'Bahia', value: 'ba' },
36 | { label: 'Ceará', value: 'ce' },
37 | { label: 'Espírito Santo', value: 'es' },
38 | { label: 'Goiás', value: 'go' },
39 | { label: 'Maranhão', value: 'ma' },
40 | { label: 'Mato Grosso', value: 'mt' },
41 | { label: 'Mato Grosso do Sul', value: 'ms' },
42 | { label: 'Minas Gerais', value: 'mg' },
43 | { label: 'Pará', value: 'pa' },
44 | { label: 'Paraíba', value: 'pb' },
45 | { label: 'Paraná', value: 'pr' },
46 | { label: 'Pernambuco', value: 'pe' },
47 | { label: 'Piauí', value: 'pi' },
48 | { label: 'Rio de Janeiro', value: 'rj' },
49 | { label: 'Rio Grande do Norte', value: 'rn' },
50 | { label: 'Rio Grande do Sul', value: 'rs' },
51 | { label: 'Rondônia', value: 'ro' },
52 | { label: 'Roraima', value: 'rr' },
53 | { label: 'Santa Catarina', value: 'sc' },
54 | { label: 'São Paulo', value: 'sp' },
55 | { label: 'Sergipe', value: 'se' },
56 | { label: 'Tocantins', value: 'to' }
57 | ]
58 |
59 | export const citiesByState: Record = {
60 | ac,
61 | al,
62 | am,
63 | ap,
64 | ba,
65 | ce,
66 | es,
67 | go,
68 | ma,
69 | mg,
70 | ms,
71 | mt,
72 | pa,
73 | pb,
74 | pe,
75 | pi,
76 | pr,
77 | rj,
78 | rn,
79 | ro,
80 | rr,
81 | rs,
82 | sc,
83 | se,
84 | sp,
85 | to
86 | }
87 |
88 | export const cities = [
89 | ...ac,
90 | ...al,
91 | ...am,
92 | ...ap,
93 | ...ba,
94 | ...ce,
95 | ...es,
96 | ...go,
97 | ...ma,
98 | ...mg,
99 | ...ms,
100 | ...mt,
101 | ...pa,
102 | ...pb,
103 | ...pe,
104 | ...pi,
105 | ...pr,
106 | ...rj,
107 | ...rn,
108 | ...ro,
109 | ...rr,
110 | ...rs,
111 | ...sc,
112 | ...se,
113 | ...sp,
114 | ...to
115 | ]
116 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Properties/index.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | Bank,
3 | Building,
4 | Car,
5 | CurrencyCircleDollar,
6 | House,
7 | Receipt,
8 | MapPinArea,
9 | Wallet
10 | } from '@phosphor-icons/react'
11 | import type { Candidate } from 'types/candidate'
12 |
13 | import styles from './styles.module.scss'
14 |
15 | const convertFloatToCurrency = (currency: string | number) => {
16 | const value = Number(currency)
17 |
18 | if (!value) {
19 | return ''
20 | }
21 |
22 | return new Intl.NumberFormat('pt-BR', {
23 | currency: 'BRL',
24 | style: 'currency'
25 | }).format(value)
26 | }
27 |
28 | export const Properties = (candidate: Candidate) => {
29 | const total = convertFloatToCurrency(candidate.totalDeBens)
30 |
31 | const getIconProperty = (type: string) => {
32 | if (type.includes('automóvel')) {
33 | return
34 | } else if (type.includes('Apartamento')) {
35 | return
36 | } else if (type.includes('Casa')) {
37 | return
38 | } else if (type.includes('Terreno')) {
39 | return
40 | } else if (
41 | type.includes('Investimentos') ||
42 | type.includes('Outros fundos')
43 | ) {
44 | return
45 | } else if (type.includes('CDB') || type.includes('conta corrente')) {
46 | return
47 | }
48 |
49 | return
50 | }
51 |
52 | const formatDescription = (value: string) => {
53 | const description = value.toLocaleLowerCase()
54 |
55 | if (
56 | description.includes('participação sociedade') ||
57 | description.includes('capital social')
58 | ) {
59 | return 'Partipação sociedade'
60 | } else if (description.includes('investimento')) {
61 | return 'Investimentos'
62 | }
63 |
64 | return description
65 | }
66 |
67 | return (
68 |
69 |
70 |
71 | Patrimônio declarado
72 | {total && {total} }
73 |
74 |
75 | {!total ? (
76 |
Não há dados registrados!
77 | ) : (
78 |
79 | {candidate.bens.map(item => (
80 |
85 |
{getIconProperty(item.descricaoDeTipoDeBem)}
86 |
87 |
88 | {formatDescription(item.descricao)}
89 | {convertFloatToCurrency(item.valor)}
90 |
91 |
92 | ))}
93 |
94 | )}
95 |
96 | )
97 | }
98 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidatos/index.page.tsx:
--------------------------------------------------------------------------------
1 | import { useParams } from 'next/navigation'
2 | import { GetStaticPaths, GetStaticProps } from 'next'
3 |
4 | import { cities } from 'data/cities'
5 | import { CandidatesProvider } from 'hooks'
6 | import { maskOnlyNumber } from 'utils/mask'
7 | import { serviceGetCandidates } from 'services'
8 | import type { CandidateSimple } from 'types/candidate'
9 |
10 | import { Layout, SEO } from 'components'
11 | import { Aside } from './components/Aside'
12 | import { Candidates } from './components/Candidates'
13 | import { FilterMobile } from './components/FilterMobile'
14 | import { CandidatesSkeleton } from './components/Skeleton'
15 |
16 | import styles from './styles.module.scss'
17 |
18 | import paths from 'data/static-paths-candidate.json'
19 |
20 | interface PageProps {
21 | mayor: CandidateSimple[]
22 | deputyMayor: CandidateSimple[]
23 | councilor: CandidateSimple[]
24 | }
25 |
26 | const CandidatesPage = ({
27 | mayor = [],
28 | deputyMayor = [],
29 | councilor = []
30 | }: PageProps) => {
31 | const params = useParams()
32 |
33 | const cityId = params?.city ? maskOnlyNumber(params.city as string) : ''
34 | const city = cities.find(c => c.value === cityId)?.label
35 |
36 | const title = `Eleições 2024 em ${city} - Confira a lista de candidatos`
37 | const description = `Veja a lista completa com nomes, partidos e números de urna dos candidatos a prefeito e vereador em ${city} nas eleições municipais de 2024.`
38 |
39 | const isLoading = mayor.length === 0 && councilor.length === 0
40 |
41 | // eslint-disable-next-line prettier/prettier
42 | const elemTitle = (<>Eleições 2024 em {city} >)
43 |
44 | return (
45 |
46 |
47 |
48 |
49 | {isLoading ? (
50 |
51 | ) : (
52 |
57 | )}
58 |
59 |
60 | )
61 | }
62 |
63 | export const getStaticPaths: GetStaticPaths = async () => {
64 | return { fallback: true, paths }
65 | }
66 |
67 | const handleRedirect = (permanent = true) => {
68 | const destination = '/nao-encontrado/cidade'
69 | return { props: {}, redirect: { destination, permanent } }
70 | }
71 |
72 | export const getStaticProps: GetStaticProps = async ({ params }) => {
73 | let cityId = (params?.city as string) ?? ''
74 | cityId = maskOnlyNumber(cityId)
75 |
76 | const isInvalidCity = !cities.find(city => city.value === cityId)
77 |
78 | if (isInvalidCity) return handleRedirect()
79 |
80 | const data = await serviceGetCandidates(cityId)
81 |
82 | if (!data) return handleRedirect(false)
83 |
84 | const revalidate = data.mayor.length === 0 ? 60 : false
85 |
86 | return { props: data, revalidate }
87 | }
88 |
89 | export default CandidatesPage
90 |
--------------------------------------------------------------------------------
/src/components/SVG/empty-state-location.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function Icon() {
4 | return (
5 |
12 |
20 |
26 |
27 | )
28 | }
29 |
30 | export default React.memo(Icon)
31 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/[id].page.tsx:
--------------------------------------------------------------------------------
1 | import classNames from 'classnames'
2 | import { GetStaticPaths, GetStaticProps } from 'next'
3 | import { Mailbox, WarningCircle } from '@phosphor-icons/react'
4 |
5 | import { cities } from 'data/cities'
6 | import { maskOnlyNumber } from 'utils/mask'
7 | import { serviceGetCandidate } from 'services'
8 | import type { Candidate } from 'types/candidate'
9 |
10 | import { Layout } from 'components'
11 | import { Profile } from './components/Profile'
12 | import { Tags } from './components/Tags'
13 | import { News } from './components/News'
14 | import { Properties } from './components/Properties'
15 | import { PreviousElections } from './components/PreviousElections'
16 | import { ShareCandidate } from './components/Share'
17 | import { Breadcrumb } from './components/Breadcrumb'
18 | import { CandidateSkeleton } from './components/Skeleton'
19 | import { InfoPoliticalParty } from './components/InfoPoliticalParty'
20 |
21 | import styles from './styles.module.scss'
22 |
23 | const CandidatePage = (candidate: Candidate) => {
24 | if (!candidate?.nomeUrna) {
25 | return
26 | }
27 |
28 | return (
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | {candidate.reelicao.eleito && (
41 |
42 |
43 |
{' '}
44 |
45 |
Releição de cargo
46 |
47 | O candidato {candidate.nomeCompleto} foi eleito em
48 | 2020 para o cargo de {candidate.cargo.nome}!
49 |
50 |
51 |
52 | {candidate.reelicao.proposta && (
53 |
58 | Acessar plano de governo de 2020
59 |
60 | )}
61 |
62 | )}
63 |
64 |
65 |
66 |
67 | {candidate.emails && (
68 |
69 |
70 |
71 | Emails para contato
72 |
73 |
74 |
{candidate.emails.join(', ')}
75 |
76 | )}
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | )
89 | }
90 |
91 | export const getStaticPaths: GetStaticPaths = async () => {
92 | return { fallback: true, paths: [] }
93 | }
94 |
95 | export const getStaticProps: GetStaticProps = async ({ params }) => {
96 | let cityId = (params?.city as string) ?? ''
97 | cityId = maskOnlyNumber(cityId)
98 |
99 | const isInvalidCity = !cities.find(city => city.value === cityId)
100 |
101 | if (isInvalidCity) {
102 | const destination = '/nao-encontrado/cidade'
103 | return { props: {}, redirect: { destination, permanent: true } }
104 | }
105 |
106 | return serviceGetCandidate(params)
107 | }
108 |
109 | export default CandidatePage
110 |
--------------------------------------------------------------------------------
/src/services/get-candidate.ts:
--------------------------------------------------------------------------------
1 | import api from 'lib/api'
2 | import type { Candidate, PreviousElection } from 'types'
3 | import type { ParsedUrlQuery } from 'querystring'
4 | import { maskOnlyNumber, maskSigla } from 'utils/mask'
5 |
6 | interface Vice {
7 | sq_CANDIDATO: number
8 | urlFoto: string
9 | nm_CANDIDATO: string
10 | nm_URNA: string
11 | }
12 |
13 | interface ResponseCandidate extends Candidate {
14 | vices: Vice[] | null
15 | }
16 |
17 | const getOtherCandidate = (vices: Vice[] | null) => {
18 | if (vices && vices.length > 0) {
19 | return {
20 | id: vices[0].sq_CANDIDATO,
21 | urlFoto: vices[0].urlFoto,
22 | nomeCompleto: vices[0].nm_CANDIDATO.toLocaleLowerCase(),
23 | nomeUrna: vices[0].nm_URNA
24 | }
25 | }
26 |
27 | return null
28 | }
29 |
30 | const getInfoReelection = async (
31 | previousElection: PreviousElection[],
32 | role: string
33 | ) => {
34 | const oldElection = previousElection.find(
35 | pe => pe.nrAno === 2020 && pe.cargo === role
36 | )
37 |
38 | const statusElection = oldElection
39 | ? oldElection.situacaoTotalizacao.toLocaleLowerCase()
40 | : ''
41 | const wasElected = ['eleito', '2º turno'].includes(statusElection)
42 |
43 | if (!oldElection || !wasElected) {
44 | return { eleito: false }
45 | }
46 |
47 | if (oldElection.cargo === 'Prefeito') {
48 | const route = `/buscar/2020/${oldElection.sgUe}/2030402020/candidato/${oldElection.id}`
49 | const { data } = await api.get(route)
50 | const file = data.arquivos.find(item => item.codTipo === '5')
51 |
52 | if (file) {
53 | const proposta = `https://divulgacandcontas.tse.jus.br/${file.url}/${file.nome}`
54 | return { eleito: true, proposta }
55 | }
56 | }
57 |
58 | return { eleito: true }
59 | }
60 |
61 | export const serviceGetCandidate = async (
62 | params: ParsedUrlQuery | undefined
63 | ): Promise<{ revalidate: boolean | number; props: Candidate }> => {
64 | let id = (params?.id as string) || '0-'
65 | id = maskOnlyNumber(id.split('-')[0])
66 | const city = maskOnlyNumber(params?.city as string)
67 |
68 | try {
69 | const route = `/buscar/2024/${city}/2045202024/candidato/${id}`
70 | const { data } = await api.get(route)
71 |
72 | const reelicao = await getInfoReelection(
73 | data.eleicoesAnteriores,
74 | data.cargo.nome
75 | )
76 |
77 | const candidate: Candidate = {
78 | nomeCompleto: data.nomeCompleto.toLocaleLowerCase(),
79 | id: data.id,
80 | numero: data.numero,
81 | nomeUrna: data.nomeUrna,
82 | fotoUrl: data.fotoUrl,
83 | partidoSigla: maskSigla(data.partido.sigla),
84 | arquivos: data.arquivos,
85 | sites: data.sites,
86 | cargo: {
87 | nome: data.cargo.nome.toLocaleLowerCase()
88 | },
89 | localCandidatura: data.localCandidatura.toLocaleLowerCase(),
90 | partido: data.partido,
91 | cnpjcampanha: data.cnpjcampanha,
92 | nomeMunicipioNascimento: data.nomeMunicipioNascimento.toLocaleLowerCase(),
93 | sgUfNascimento: data.sgUfNascimento,
94 | dataDeNascimento: data.dataDeNascimento,
95 | grauInstrucao: data.grauInstrucao,
96 | ocupacao: data.ocupacao.toLocaleLowerCase(),
97 | emails: data.emails,
98 | totalDeBens: data.totalDeBens,
99 | ufSuperiorCandidatura: data.ufSuperiorCandidatura.toLocaleLowerCase(),
100 | bens: data.bens,
101 | eleicoesAnteriores: data.eleicoesAnteriores,
102 | otherCandidate: getOtherCandidate(data?.vices),
103 | nomeColigacao: data.nomeColigacao,
104 | composicaoColigacao: data.composicaoColigacao,
105 | reelicao
106 | }
107 |
108 | return { props: candidate, revalidate: false }
109 | } catch (e) {
110 | console.log(e)
111 | }
112 |
113 | return { props: {} as never, revalidate: 60 }
114 | }
115 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidatos/components/Candidates/index.tsx:
--------------------------------------------------------------------------------
1 | import classNames from 'classnames'
2 | import { useRouter } from 'next/router'
3 | import { BookmarkSimple } from '@phosphor-icons/react'
4 |
5 | import { useCandidates } from 'hooks'
6 | import { maskToParamsURL, normalizeString } from 'utils/mask'
7 | import type { Candidate, CandidateSimple } from 'types/candidate'
8 |
9 | import styles from './styles.module.scss'
10 |
11 | const Candidate = (candidate: CandidateSimple) => {
12 | const { asPath } = useRouter()
13 | const baseUrl = asPath.split('/candidatos')[0]
14 |
15 | const code = candidate.numero.toString().split('')
16 | const name = maskToParamsURL(candidate.nomeUrna)
17 |
18 | const href = baseUrl + `/candidato/${candidate.id}-${name}`
19 |
20 | return (
21 |
22 |
23 |
{candidate.nomeUrna}
24 |
{candidate.nomeCompleto}
25 |
26 |
27 |
28 | {code.map((item, index) => (
29 | {item}
30 | ))}
31 |
32 |
33 | )
34 | }
35 |
36 | interface SectionProps {
37 | title?: string
38 | candidates: CandidateSimple[]
39 | }
40 |
41 | const Section = ({ title = '', candidates }: SectionProps) => (
42 |
43 | {title && (
44 |
45 |
46 | {title}
47 |
48 | )}
49 |
50 | {candidates.length === 0 ? (
51 | A lista de candidatos está vazia.
52 | ) : (
53 |
54 | {candidates.map(candidate => (
55 |
56 | ))}
57 |
58 | )}
59 |
60 | )
61 |
62 | export const Candidates = () => {
63 | const { candidates, filter } = useCandidates()
64 |
65 | // TODO - Add empty state
66 | if (candidates.councilor.length === 0 && candidates.mayor.length === 0) {
67 | return <>>
68 | }
69 |
70 | const clearString = (str: string) => {
71 | if (!str) return ''
72 | return normalizeString(str).toLocaleLowerCase()
73 | }
74 |
75 | const handleFilterCandidates = (list: CandidateSimple[]) => {
76 | const search = clearString(filter.candidateName)
77 |
78 | if (!search && filter.parties.length === 0) {
79 | return list
80 | }
81 |
82 | return list.filter(candidate => {
83 | let isMatch = true
84 | const { nomeUrna, nomeCompleto, partidoSigla } = candidate
85 |
86 | if (filter.parties.length > 0) {
87 | isMatch = filter.parties.includes(partidoSigla)
88 | }
89 |
90 | if (isMatch && search.length > 0) {
91 | isMatch =
92 | clearString(nomeUrna).includes(search) ||
93 | clearString(nomeCompleto).includes(search)
94 | }
95 |
96 | return isMatch
97 | })
98 | }
99 |
100 | const mayorFiltered = handleFilterCandidates(candidates.mayor)
101 | const deputyMayorFiltered = handleFilterCandidates(candidates.deputyMayor)
102 | const councilorFiltered = handleFilterCandidates(candidates.councilor)
103 |
104 | if (filter.role) {
105 | // eslint-disable-next-line prettier/prettier
106 | if (filter.role === 'prefeito') return
107 | // eslint-disable-next-line prettier/prettier
108 | if (filter.role === 'vice') return
109 | return
110 | }
111 |
112 | return (
113 |
114 |
115 |
116 |
117 |
118 | )
119 | }
120 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidatos/components/Aside/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | width: 100%;
3 | max-width: 300px;
4 |
5 | display: flex;
6 | flex-direction: column;
7 | row-gap: 24px;
8 |
9 | margin-top: 40px;
10 |
11 | @media(max-width: 1000px) {
12 | margin-top: 0;
13 | max-width: 100%;
14 | row-gap: 16px;
15 | }
16 |
17 | @media(max-width: 650px) {
18 | row-gap: 20px;
19 | }
20 | }
21 |
22 | .form {
23 | display: flex;
24 | flex-direction: column;
25 | row-gap: 16px;
26 |
27 | fieldset {
28 | display: flex;
29 | flex-direction: column;
30 | row-gap: 4px;
31 |
32 | label {
33 | font-size: 14px;
34 | }
35 |
36 | // Select value
37 | > div > div > div {
38 | text-transform: capitalize;
39 | }
40 | }
41 |
42 | @media(max-width: 1000px) {
43 | width: 100%;
44 | flex-direction: row;
45 | align-items: flex-end;
46 |
47 | gap: 16px;
48 |
49 | fieldset {
50 | flex: 1;
51 | }
52 |
53 | > button {
54 | width: 150px;
55 | }
56 | }
57 |
58 | @media(max-width: 650px) {
59 | flex-direction: column;
60 | align-items: stretch;
61 |
62 | > button {
63 | width: 100%;
64 | }
65 | }
66 | }
67 |
68 | .search {
69 | display: flex;
70 | align-items: center;
71 | column-gap: 8px;
72 |
73 | border-radius: 6px;
74 | border: 1px solid hsl(0, 0%, 80%);
75 | background: #fff;
76 | padding: 7px 7px 7px 12px;
77 |
78 | > input {
79 | flex: 1;
80 | border: 0;
81 | background: transparent;
82 | outline: none;
83 | }
84 |
85 | &:focus-within {
86 | border: thin solid var(--blue);
87 | }
88 | }
89 |
90 | .roles {
91 | display: grid;
92 | grid-template-columns: 1fr 1fr 1fr;
93 | column-gap: 8px;
94 |
95 | button {
96 | font-size: 15px;
97 | text-align: center;
98 |
99 | padding: 4px 0;
100 | border-radius: 16px;
101 | background-color: transparent;
102 | border: 2px solid var(--green);
103 |
104 | transition: all 0.4s;
105 |
106 | &.role__active, &:hover {
107 | color: #fff;
108 | background-color: var(--green);
109 | }
110 | }
111 | }
112 |
113 | .form__button {
114 | padding: 8px 24px;
115 | border-radius: 6px;
116 | color: #fff;
117 | background-color: var(--blue);
118 |
119 | transition: all 0.4s;
120 |
121 | &:disabled {
122 | position: relative;
123 | background-color: #007bffa9;
124 |
125 | &[data-state="loading"]{
126 | color: transparent;
127 | }
128 | }
129 |
130 | &[data-state="loading"]::after {
131 | content: '';
132 | position: absolute;
133 | inset: 0;
134 | margin: auto;
135 | display: block;
136 | width: 20px;
137 | height: 20px;
138 | background: transparent;
139 |
140 | border-radius: 50%;
141 | border: 1px solid transparent;
142 | border-left-color: #fff;
143 |
144 | animation: rotation 1s linear infinite;
145 |
146 | @keyframes rotation {
147 | 0% {
148 | transform: rotate(0deg);
149 | }
150 | 100% {
151 | transform: rotate(360deg);
152 | }
153 | }
154 | }
155 | }
156 |
157 |
158 | .filter__parties {
159 | display: flex;
160 | flex-direction: column;
161 | row-gap: 12px;
162 |
163 | button {
164 | display: flex;
165 | align-items: center;
166 | column-gap: 12px;
167 |
168 | border: 0;
169 | height: 40px;
170 | border-radius: 2px;
171 | padding: 0 6px;
172 | background: #fff;
173 | box-shadow: var(--shadow-border);
174 |
175 | transition: all 0.4s;
176 |
177 | p,
178 | span {
179 | font-size: 14px;
180 | text-align: left;
181 | line-height: 1.2;
182 | }
183 |
184 | span {
185 | margin-left: auto;
186 | }
187 |
188 | &[aria-pressed='false'] {
189 | filter: grayscale(1);
190 | opacity: 0.4;
191 | }
192 |
193 | &:hover {
194 | filter: grayscale(0);
195 | opacity: 1;
196 | }
197 | }
198 |
199 | @media(max-width: 1000px) {
200 | display: grid;
201 | grid-template-columns: 1fr 1fr 1fr;
202 | gap: 16px;
203 | }
204 |
205 | @media(max-width: 768px) {
206 | grid-template-columns: 1fr 1fr;
207 | }
208 |
209 | @media(max-width: 650px) {
210 | grid-template-columns: 1fr;
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/src/data/cities/ro.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "00310",
4 | "label": "alta floresta d'oeste"
5 | },
6 | {
7 | "value": "00736",
8 | "label": "alto alegre dos parecis"
9 | },
10 | {
11 | "value": "00639",
12 | "label": "alto paraíso"
13 | },
14 | {
15 | "value": "00337",
16 | "label": "alvorada do oeste"
17 | },
18 | {
19 | "value": "00078",
20 | "label": "ariquemes"
21 | },
22 | {
23 | "value": "00779",
24 | "label": "buritis"
25 | },
26 | {
27 | "value": "00450",
28 | "label": "cabixi"
29 | },
30 | {
31 | "value": "00620",
32 | "label": "cacaulândia"
33 | },
34 | {
35 | "value": "00094",
36 | "label": "cacoal"
37 | },
38 | {
39 | "value": "00671",
40 | "label": "campo novo de rondônia"
41 | },
42 | {
43 | "value": "00477",
44 | "label": "candeias do jamari"
45 | },
46 | {
47 | "value": "00531",
48 | "label": "castanheiras"
49 | },
50 | {
51 | "value": "00272",
52 | "label": "cerejeiras"
53 | },
54 | {
55 | "value": "00809",
56 | "label": "chupinguaia"
57 | },
58 | {
59 | "value": "00230",
60 | "label": "colorado do oeste"
61 | },
62 | {
63 | "value": "00655",
64 | "label": "corumbiara"
65 | },
66 | {
67 | "value": "00213",
68 | "label": "costa marques"
69 | },
70 | {
71 | "value": "00680",
72 | "label": "cujubim"
73 | },
74 | {
75 | "value": "00256",
76 | "label": "espigão do oeste"
77 | },
78 | {
79 | "value": "00612",
80 | "label": "governador jorge teixeira"
81 | },
82 | {
83 | "value": "00019",
84 | "label": "guajará-mirim"
85 | },
86 | {
87 | "value": "00493",
88 | "label": "itapuã do oeste"
89 | },
90 | {
91 | "value": "00159",
92 | "label": "jaru"
93 | },
94 | {
95 | "value": "00051",
96 | "label": "ji-paraná"
97 | },
98 | {
99 | "value": "00396",
100 | "label": "machadinho d'oeste"
101 | },
102 | {
103 | "value": "00604",
104 | "label": "ministro andreazza"
105 | },
106 | {
107 | "value": "00574",
108 | "label": "mirante da serra"
109 | },
110 | {
111 | "value": "00663",
112 | "label": "monte negro"
113 | },
114 | {
115 | "value": "00370",
116 | "label": "nova brasilândia d'oeste"
117 | },
118 | {
119 | "value": "00434",
120 | "label": "nova mamoré"
121 | },
122 | {
123 | "value": "00744",
124 | "label": "nova união"
125 | },
126 | {
127 | "value": "00515",
128 | "label": "novo horizonte do oeste"
129 | },
130 | {
131 | "value": "00175",
132 | "label": "ouro preto do oeste"
133 | },
134 | {
135 | "value": "00701",
136 | "label": "parecis"
137 | },
138 | {
139 | "value": "00116",
140 | "label": "pimenta bueno"
141 | },
142 | {
143 | "value": "00787",
144 | "label": "pimenteiras do oeste"
145 | },
146 | {
147 | "value": "00035",
148 | "label": "porto velho"
149 | },
150 | {
151 | "value": "00191",
152 | "label": "presidente médici"
153 | },
154 | {
155 | "value": "00728",
156 | "label": "primavera de rondônia"
157 | },
158 | {
159 | "value": "00647",
160 | "label": "rio crespo"
161 | },
162 | {
163 | "value": "00299",
164 | "label": "rolim de moura"
165 | },
166 | {
167 | "value": "00353",
168 | "label": "santa luzia d'oeste"
169 | },
170 | {
171 | "value": "00710",
172 | "label": "são felipe d'oeste"
173 | },
174 | {
175 | "value": "00795",
176 | "label": "são francisco do guaporé"
177 | },
178 | {
179 | "value": "00418",
180 | "label": "são miguel do guaporé"
181 | },
182 | {
183 | "value": "00582",
184 | "label": "seringueiras"
185 | },
186 | {
187 | "value": "00752",
188 | "label": "teixeirópolis"
189 | },
190 | {
191 | "value": "00590",
192 | "label": "theobroma"
193 | },
194 | {
195 | "value": "00566",
196 | "label": "urupá"
197 | },
198 | {
199 | "value": "00698",
200 | "label": "vale do anari"
201 | },
202 | {
203 | "value": "00558",
204 | "label": "vale do paraíso"
205 | },
206 | {
207 | "value": "00132",
208 | "label": "vilhena"
209 | }
210 | ]
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Profile/styles.module.scss:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: stretch;
5 | row-gap: 32px;
6 |
7 | width: 350px;
8 |
9 | top: 32px;
10 | position: sticky;
11 |
12 | @media(max-width: 1000px) {
13 | position: relative;
14 | top: 0;
15 |
16 | width: 100%;
17 | }
18 | }
19 |
20 | .candidate {
21 | padding: 0 0 24px;
22 |
23 | .flag {
24 | width: 100%;
25 | height: 200px;
26 | display: block;
27 |
28 | img {
29 | width: 100%;
30 | height: 100%;
31 | object-fit: cover;
32 | }
33 | }
34 |
35 | @media(max-width: 1000px) {
36 | padding: 20px 20px 40px;
37 |
38 | .flag {
39 | display: none;
40 | }
41 | }
42 |
43 | @media(max-width: 650px) {
44 | padding: 16px;
45 | }
46 | }
47 |
48 | .profile__content {
49 | display: flex;
50 | flex-direction: column;
51 | align-items: center;
52 | row-gap: 12px;
53 |
54 | margin-top: -84px;
55 |
56 | text-align: center;
57 |
58 | .profile__image {
59 | width: 140px;
60 | height: 180px;
61 | border-radius: 20px;
62 | border: 4px solid #fff;
63 | overflow: hidden;
64 |
65 | grid-row: 1 / 5;
66 |
67 | img {
68 | width: 100%;
69 | height: 100%;
70 | object-fit: cover;
71 | }
72 | }
73 |
74 | .code {
75 | display: flex;
76 | column-gap: 4px;
77 |
78 | span {
79 | background: var(--green);
80 | padding: 3px 6px;
81 | border-radius: 2px;
82 | color: #fff;
83 | font-size: 24px;
84 | }
85 | }
86 |
87 | h1 {
88 | font-size: 30px;
89 | letter-spacing: -0.5px;
90 | padding: 0 8px;
91 | text-transform: capitalize;
92 | }
93 |
94 | p.description {
95 | font-size: 16px;
96 | line-height: 1.6;
97 | padding: 0 16px;
98 |
99 | i {
100 | font-weight: 500;
101 | color: var(--blue);
102 |
103 | &:not(:first-child) {
104 | text-transform: capitalize;
105 | }
106 | }
107 | }
108 |
109 | aside {
110 | display: flex;
111 | align-items: center;
112 | column-gap: 8px;
113 |
114 | a {
115 | color: var(--text);
116 | opacity: 0.7;
117 | transition: all 0.3s;
118 |
119 | &:hover {
120 | opacity: 1;
121 | transform: translateY(-5px);
122 | }
123 | }
124 | }
125 |
126 | > a {
127 | margin: 8px 0;
128 |
129 | width: 270px;
130 | padding: 10px 0;
131 | color: #fff;
132 | font-size: 18px;
133 | font-weight: 500;
134 | border-radius: 8px;
135 | background-color: #fc364f;
136 |
137 | display: flex;
138 | align-items: center;
139 | justify-content: center;
140 | column-gap: 4px;
141 |
142 | transition: all 0.3s;
143 |
144 | &:hover {
145 | background-color: #fc3650d7;
146 | }
147 |
148 | }
149 |
150 | @media(max-width: 1000px) {
151 | margin-top: 0;
152 | display: grid;
153 | gap: 0;
154 | grid-template-columns: 140px 1fr;
155 |
156 | position: relative;
157 |
158 | img {
159 | border-radius: 12px;
160 | border: 2px solid var(--background);
161 | }
162 |
163 | .code {
164 | position: absolute;
165 | bottom: -16px;
166 | left: 0;
167 | width: 140px;
168 | justify-content: center;
169 | }
170 |
171 | h1 {
172 | font-size: 28px;
173 | padding: 0;
174 | }
175 |
176 | p.description {
177 | margin: 0 auto;
178 | max-width: 500px;
179 | width: 100%;
180 | }
181 |
182 | aside {
183 | margin: 8px 0;
184 | justify-content: center;
185 | }
186 |
187 | > a {
188 | grid-row-start: 4;
189 | margin: 0 auto;
190 |
191 | width: auto;
192 | padding: 6px 16px;
193 | font-size: 16px;
194 | }
195 | }
196 |
197 | @media(max-width: 650px) {
198 | display: flex;
199 | row-gap: 8px;
200 |
201 | img {
202 | border-radius: 12px;
203 | border: 2px solid var(--background);
204 | }
205 |
206 | .code {
207 | position: relative;
208 | inset: inherit;
209 | width: 100%;
210 | }
211 |
212 | p.description {
213 | font-size: 15px;
214 | padding: 0;
215 | }
216 |
217 | aside {
218 | margin: 0;
219 | justify-content: center;
220 | }
221 |
222 | > a {
223 | margin: 8px auto;
224 | }
225 | }
226 | }
227 |
228 | .otherCandidate {
229 | display: flex;
230 | align-items: center;
231 | column-gap: 12px;
232 |
233 | padding: 12px;
234 |
235 | @media(max-width: 1000px) {
236 | display: none;
237 | }
238 |
239 | picture {
240 | width: 64px;
241 | height: 64px;
242 | border-radius: 8px;
243 | overflow: hidden;
244 |
245 | img {
246 | width: 100%;
247 | height: 100%;
248 | object-fit: cover;
249 | object-position: 0 -8px;
250 | }
251 | }
252 |
253 | div {
254 | strong, p {
255 | line-height: 1;
256 | display: block;
257 | text-transform: capitalize;
258 | }
259 |
260 | strong {
261 | font-size: 20px;
262 | font-weight: 600;
263 | margin-bottom: 4px;
264 | }
265 |
266 | p {
267 | color: var(--text-secondary);
268 | font-size: 16px;
269 | }
270 | }
271 | }
272 |
--------------------------------------------------------------------------------
/src/data/cities/am.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "02895",
4 | "label": "alvarães"
5 | },
6 | {
7 | "value": "02917",
8 | "label": "amaturá"
9 | },
10 | {
11 | "value": "02933",
12 | "label": "anamã"
13 | },
14 | {
15 | "value": "02038",
16 | "label": "anori"
17 | },
18 | {
19 | "value": "02003",
20 | "label": "apuí"
21 | },
22 | {
23 | "value": "02054",
24 | "label": "atalaia do norte"
25 | },
26 | {
27 | "value": "02070",
28 | "label": "autazes"
29 | },
30 | {
31 | "value": "02097",
32 | "label": "barcelos"
33 | },
34 | {
35 | "value": "02119",
36 | "label": "barreirinha"
37 | },
38 | {
39 | "value": "02135",
40 | "label": "benjamin constant"
41 | },
42 | {
43 | "value": "02950",
44 | "label": "beruri"
45 | },
46 | {
47 | "value": "02976",
48 | "label": "boa vista do ramos"
49 | },
50 | {
51 | "value": "02151",
52 | "label": "boca do acre"
53 | },
54 | {
55 | "value": "02178",
56 | "label": "borba"
57 | },
58 | {
59 | "value": "02992",
60 | "label": "caapiranga"
61 | },
62 | {
63 | "value": "02194",
64 | "label": "canutama"
65 | },
66 | {
67 | "value": "02216",
68 | "label": "carauari"
69 | },
70 | {
71 | "value": "02232",
72 | "label": "careiro"
73 | },
74 | {
75 | "value": "02046",
76 | "label": "careiro da várzea"
77 | },
78 | {
79 | "value": "02259",
80 | "label": "coari"
81 | },
82 | {
83 | "value": "02275",
84 | "label": "codajás"
85 | },
86 | {
87 | "value": "02291",
88 | "label": "eirunepé"
89 | },
90 | {
91 | "value": "02313",
92 | "label": "envira"
93 | },
94 | {
95 | "value": "02330",
96 | "label": "fonte boa"
97 | },
98 | {
99 | "value": "02020",
100 | "label": "guajará"
101 | },
102 | {
103 | "value": "02356",
104 | "label": "humaitá"
105 | },
106 | {
107 | "value": "02399",
108 | "label": "ipixuna"
109 | },
110 | {
111 | "value": "98353",
112 | "label": "iranduba"
113 | },
114 | {
115 | "value": "02410",
116 | "label": "itacoatiara"
117 | },
118 | {
119 | "value": "98370",
120 | "label": "itamarati"
121 | },
122 | {
123 | "value": "02437",
124 | "label": "itapiranga"
125 | },
126 | {
127 | "value": "02453",
128 | "label": "japurá"
129 | },
130 | {
131 | "value": "02470",
132 | "label": "juruá"
133 | },
134 | {
135 | "value": "02496",
136 | "label": "jutaí"
137 | },
138 | {
139 | "value": "02518",
140 | "label": "lábrea"
141 | },
142 | {
143 | "value": "02534",
144 | "label": "manacapuru"
145 | },
146 | {
147 | "value": "98396",
148 | "label": "manaquiri"
149 | },
150 | {
151 | "value": "02550",
152 | "label": "manaus"
153 | },
154 | {
155 | "value": "02577",
156 | "label": "manicoré"
157 | },
158 | {
159 | "value": "02593",
160 | "label": "maraã"
161 | },
162 | {
163 | "value": "02615",
164 | "label": "maués"
165 | },
166 | {
167 | "value": "02631",
168 | "label": "nhamundá"
169 | },
170 | {
171 | "value": "02658",
172 | "label": "nova olinda do norte"
173 | },
174 | {
175 | "value": "02011",
176 | "label": "novo airão"
177 | },
178 | {
179 | "value": "02674",
180 | "label": "novo aripuanã"
181 | },
182 | {
183 | "value": "02690",
184 | "label": "parintins"
185 | },
186 | {
187 | "value": "02712",
188 | "label": "pauini"
189 | },
190 | {
191 | "value": "98418",
192 | "label": "presidente figueiredo"
193 | },
194 | {
195 | "value": "98434",
196 | "label": "rio preto da eva"
197 | },
198 | {
199 | "value": "02372",
200 | "label": "santa isabel do rio negro"
201 | },
202 | {
203 | "value": "02739",
204 | "label": "santo antônio do içá"
205 | },
206 | {
207 | "value": "02836",
208 | "label": "são gabriel da cachoeira"
209 | },
210 | {
211 | "value": "02755",
212 | "label": "são paulo de olivença"
213 | },
214 | {
215 | "value": "98450",
216 | "label": "são sebastião do uatumã"
217 | },
218 | {
219 | "value": "02771",
220 | "label": "silves"
221 | },
222 | {
223 | "value": "98477",
224 | "label": "tabatinga"
225 | },
226 | {
227 | "value": "02798",
228 | "label": "tapauá"
229 | },
230 | {
231 | "value": "02810",
232 | "label": "tefé"
233 | },
234 | {
235 | "value": "98515",
236 | "label": "tonantins"
237 | },
238 | {
239 | "value": "98493",
240 | "label": "uarini"
241 | },
242 | {
243 | "value": "02852",
244 | "label": "urucará"
245 | },
246 | {
247 | "value": "02879",
248 | "label": "urucurituba"
249 | }
250 | ]
--------------------------------------------------------------------------------
/src/data/partidos.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | pode: {
3 | name: 'Podemos',
4 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-trabalhista-nacional',
5 | image: '/icons/PODE.png'
6 | },
7 | psd: {
8 | name: 'Partido Social Democrático',
9 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-social-democratico',
10 | image: '/icons/PSD.png'
11 | },
12 | republicanos: {
13 | name: 'Republicanos',
14 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/republicanos',
15 | image: '/icons/REPUBLICANOS.png'
16 | },
17 | pl: {
18 | name: 'Partido Liberal',
19 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-da-republica',
20 | image: '/icons/PL.png'
21 | },
22 | pp: {
23 | name: 'Progressistas',
24 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-progressista',
25 | image: '/icons/PP.png'
26 | },
27 | pdt: {
28 | name: 'Partido Democrático Trabalhista',
29 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-democratico-trabalhista',
30 | image: '/icons/PDT.png'
31 | },
32 | uniao: {
33 | name: 'União',
34 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/uniao-brasil',
35 | image: '/icons/UNIAO.png'
36 | },
37 | pt: {
38 | name: 'Partido dos Trabalhadores',
39 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-dos-trabalhadores',
40 | image: '/icons/PT.png'
41 | },
42 | mdb: {
43 | name: 'Movimento Democrático Brasileiro',
44 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/movimento-democratico-brasileiro',
45 | image: '/icons/MDB.png'
46 | },
47 | pcdob: {
48 | name: 'Partido Comunista do Brasil',
49 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-comunista-do-brasil',
50 | image: '/icons/PCDOB.png'
51 | },
52 | novo: {
53 | name: 'Partido Novo',
54 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-novo',
55 | image: '/icons/NOVO.png'
56 | },
57 | psol: {
58 | name: 'Partido Socialismo e Liberdade',
59 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-socialismo-e-liberdade',
60 | image: '/icons/PSOL.png'
61 | },
62 | pstu: {
63 | name: 'Partido Socialista dos Trabalhadores Unificado',
64 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-socialista-dos-trabalhadores-unificado',
65 | image: '/icons/PSTU.png'
66 | },
67 | dc: {
68 | name: 'Democracia Cristã',
69 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-social-democrata-cristao',
70 | image: '/icons/DC.png'
71 | },
72 | pco: {
73 | name: 'Partido da Causa Operária',
74 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-da-causa-operaria',
75 | image: '/icons/PCO.png'
76 | },
77 | prtb: {
78 | name: 'Partido Renovador Trabalhista Brasileiro',
79 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-renovador-trabalhista-brasileiro',
80 | image: '/icons/PRTB.png'
81 | },
82 | up: {
83 | name: 'Unidade Popular',
84 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/unidade-popular',
85 | image: '/icons/UP.png'
86 | },
87 | solidariedade: {
88 | name: 'Solidariedade',
89 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/solidariedade',
90 | image: '/icons/SOLIDARIEDADE.png'
91 | },
92 | avante: {
93 | name: 'Avante',
94 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-trabalhista-do-brasil',
95 | image: '/icons/AVANTE.png'
96 | },
97 | prd: {
98 | name: 'Partido Renovação Democrática',
99 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-renovacao-democratica-prd',
100 | image: '/icons/PRD.png'
101 | },
102 | mobiliza: {
103 | name: 'Mobilização Nacional',
104 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-da-mobilizacao-nacional',
105 | image: '/icons/MOBILIZA.png'
106 | },
107 | pmb: {
108 | name: 'Partido da Mulher Brasileira',
109 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-da-mulher-brasileira',
110 | image: '/icons/PMB.png'
111 | },
112 | rede: {
113 | name: 'Rede Sustentabilidade',
114 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/rede',
115 | image: '/icons/REDE.png'
116 | },
117 | agir: {
118 | name: 'Agir',
119 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/agir',
120 | image: '/icons/AGIR.png'
121 | },
122 | pcb: {
123 | name: 'Partido Comunista Brasileiro',
124 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-comunista-brasileiro',
125 | image: '/icons/PCB.png'
126 | },
127 | cidadania: {
128 | name: 'Cidadania',
129 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/cidadania',
130 | image: '/icons/CIDADANIA.png'
131 | },
132 | pv: {
133 | name: 'Partido Verde',
134 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-verde',
135 | image: '/icons/PV.png'
136 | },
137 | psb: {
138 | name: 'Partido Socialista Brasileiro',
139 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-socialista-brasileiro',
140 | image: '/icons/PSB.png'
141 | },
142 | psdb: {
143 | name: 'Partido da Social Democracia Brasileira',
144 | link: 'https://www.tse.jus.br/partidos/partidos-registrados-no-tse/partido-da-social-democracia-brasileira',
145 | image: '/icons/PSDB.png'
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidato/components/Profile/index.tsx:
--------------------------------------------------------------------------------
1 | import { SEO } from 'components'
2 | import classNames from 'classnames'
3 | import type { SocialLink, TypeLink, Candidate } from 'types'
4 | import {
5 | FacebookLogo,
6 | FileText,
7 | InstagramLogo,
8 | XLogo,
9 | YoutubeLogo,
10 | ThreadsLogo,
11 | TiktokLogo,
12 | LinkSimple,
13 | TelegramLogo,
14 | LinkedinLogo
15 | } from '@phosphor-icons/react'
16 | import { capitalizeString, maskToParamsURL } from 'utils/mask'
17 |
18 | import styles from './styles.module.scss'
19 | import Link from 'next/link'
20 | import { useRouter } from 'next/router'
21 |
22 | const icons: Record = {
23 | default: ,
24 | youtube: ,
25 | x: ,
26 | facebook: ,
27 | instagram: ,
28 | threads: ,
29 | tiktok: ,
30 | linkedin: ,
31 | telegram:
32 | }
33 |
34 | const handleLinksCandidate = (sites: string[]): SocialLink[] => {
35 | return sites.reduce((acc, url) => {
36 | let type = 'default'
37 |
38 | if (url.includes('youtube.com')) {
39 | type = 'youtube'
40 | } else if (url.includes('x.com')) {
41 | type = 'x'
42 | } else if (url.includes('facebook.com')) {
43 | type = 'facebook'
44 | } else if (url.includes('instagram.com')) {
45 | type = 'instagram'
46 | } else if (url.includes('threads.net')) {
47 | type = 'threads'
48 | } else if (url.includes('tiktok.com')) {
49 | type = 'tiktok'
50 | } else if (url.includes('https://t.me')) {
51 | type = 'telegram'
52 | } else if (url.includes('linkedin.com')) {
53 | type = 'linkedin'
54 | }
55 |
56 | return [...acc, { type, url }] as never
57 | }, [])
58 | }
59 |
60 | export const OtherCandidate = ({ otherCandidate: candidate }: Candidate) => {
61 | const { asPath } = useRouter()
62 |
63 | if (!candidate) {
64 | return <>>
65 | }
66 |
67 | const baseUrl = asPath.split('/candidato')[0]
68 | const pathName = maskToParamsURL(candidate.nomeUrna)
69 | const candidateUrl = `${baseUrl}/candidato/${candidate.id}-${pathName}`
70 |
71 | return (
72 |
76 |
77 |
82 |
83 |
84 |
85 |
{candidate.nomeUrna}
86 |
{candidate.nomeCompleto}
87 |
88 |
89 | )
90 | }
91 |
92 | export const Profile = (candidate: Candidate) => {
93 | const proposta = candidate.arquivos.find(item => item.codTipo === '5')
94 |
95 | const links = handleLinksCandidate(candidate.sites)
96 | const code = candidate.numero.toString().split('')
97 |
98 | const candidateName = capitalizeString(candidate.nomeUrna.toLocaleLowerCase())
99 | const seoTitle = `Candidato(a) ${candidateName} - Eleições 2024`
100 |
101 | const role = candidate.cargo.nome.toLocaleLowerCase()
102 | const city = capitalizeString(candidate.localCandidatura)
103 | const acronym = candidate.partido.sigla
104 | const seoDescription = `Confira os dados do candidato(a) que está concorrendo ao cargo de ${role} no município de ${city} pelo partido ${acronym}`
105 |
106 | return (
107 |
108 |
109 |
110 |
111 |
112 |
117 |
118 |
119 |
120 |
121 |
125 |
126 |
127 |
128 | {code.map((item, index) => (
129 | {item}
130 | ))}
131 |
132 |
133 |
{candidate.nomeUrna}
134 |
135 |
136 | O candidato(a) está concorrendo ao{' '}
137 | cargo de {candidate.cargo.nome} no município de{' '}
138 | {candidate.localCandidatura} pelo partido{' '}
139 | {candidate.partido.sigla} .
140 |
141 |
142 | {proposta && (
143 |
148 |
149 | Proposta de governo
150 |
151 | )}
152 |
153 |
166 |
167 |
168 |
169 |
170 |
171 | )
172 | }
173 |
--------------------------------------------------------------------------------
/src/pages/[state]/[city]/candidatos/components/Aside/index.tsx:
--------------------------------------------------------------------------------
1 | import Select, { SelectInstance } from 'react-select'
2 | import { useRouter } from 'next/router'
3 | import { useParams } from 'next/navigation'
4 | import { MagnifyingGlass } from '@phosphor-icons/react'
5 | import { ChangeEvent, FormEvent, useEffect, useRef, useState } from 'react'
6 |
7 | import type { Option } from 'types'
8 | import { useCandidates } from 'hooks'
9 | import listParties from 'data/partidos'
10 | import { citiesByState, states } from 'data/cities/'
11 | import { maskOnlyNumber, maskToParamsURL } from 'utils/mask'
12 |
13 | import styles from './styles.module.scss'
14 |
15 | type Sigla = keyof typeof listParties
16 |
17 | interface AsideProps {
18 | isDisabledAction?: boolean
19 | }
20 |
21 | export const Aside = ({ isDisabledAction = false }: AsideProps) => {
22 | const {
23 | candidates: data,
24 | filter,
25 | handleChangeFilter,
26 | handleChangeFilterParties
27 | } = useCandidates()
28 |
29 | const candidates = data.mayor.concat(data.councilor)
30 |
31 | const params = useParams()
32 | const { query, ...router } = useRouter()
33 |
34 | const [state, setState] = useState()
35 | const [city, setCity] = useState ()
36 | const [loading, setLoading] = useState(false)
37 | const [timeoutId, setTimeoutId] = useState(null)
38 |
39 | const cities = state ? citiesByState[state.value] : []
40 |
41 | const parties = candidates.reduce((acc, item) => {
42 | const key = item.partidoSigla
43 | acc[key] = acc[key] ? acc[key] + 1 : 1
44 |
45 | return acc
46 | }, {} as Record)
47 |
48 | const handleSearchCandidates = async (event: FormEvent) => {
49 | event.preventDefault()
50 |
51 | if (city && state) {
52 | const cityPath = city.value + '-' + maskToParamsURL(city.label)
53 | const route = `/${state.value}/${cityPath}/candidatos/`
54 |
55 | router.push(route)
56 | setLoading(true)
57 | }
58 | }
59 |
60 | useEffect(() => {
61 | if (params?.state && params?.city) {
62 | loading && setLoading(false)
63 | setState(states.find(s => s.value === query.state))
64 |
65 | const city = maskOnlyNumber(params.city as string)
66 | setCity(citiesByState[query.state as string].find(c => c.value === city))
67 | }
68 | }, [params])
69 |
70 | const refSelect = useRef>(null)
71 |
72 | const handleChangeState = (value: Option | null) => {
73 | setState(value)
74 | setCity(null)
75 | refSelect?.current && refSelect.current.focus()
76 | }
77 |
78 | const handleNameChange = (e: ChangeEvent) => {
79 | const candidateName = e.target.value.trimStart()
80 |
81 | timeoutId && clearTimeout(timeoutId)
82 | setTimeoutId(setTimeout(() => handleChangeFilter({ candidateName }), 500))
83 | }
84 |
85 | const handleChangeFilterRole = (role: string) => {
86 | const isClear = role === filter.role
87 | handleChangeFilter({ role: isClear ? '' : role })
88 | }
89 |
90 | return (
91 |
92 |
126 |
127 |
128 |
129 |
136 |
137 |
138 |
139 | handleChangeFilterRole('prefeito')}
147 | >
148 | Prefeito
149 |
150 | handleChangeFilterRole('vice')}
156 | >
157 | Vice
158 |
159 | handleChangeFilterRole('vereador')}
167 | >
168 | Vereador
169 |
170 |
171 |
172 |
173 | {Object.keys(parties).map(party => (
174 |
handleChangeFilterParties(party)}
178 | aria-pressed={
179 | filter.parties.includes(party) || filter.parties.length === 0
180 | }
181 | >
182 |
190 | {listParties[party.toLocaleLowerCase() as Sigla]?.name}
191 | ({parties[party]})
192 |
193 | ))}
194 |
195 |
196 | )
197 | }
198 |
--------------------------------------------------------------------------------
/src/data/cities/se.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "31011",
4 | "label": "amparo de são francisco"
5 | },
6 | {
7 | "value": "31038",
8 | "label": "aquidabã"
9 | },
10 | {
11 | "value": "31054",
12 | "label": "aracaju"
13 | },
14 | {
15 | "value": "31070",
16 | "label": "arauá"
17 | },
18 | {
19 | "value": "31097",
20 | "label": "areia branca"
21 | },
22 | {
23 | "value": "31119",
24 | "label": "barra dos coqueiros"
25 | },
26 | {
27 | "value": "31151",
28 | "label": "boquim"
29 | },
30 | {
31 | "value": "31135",
32 | "label": "brejo grande"
33 | },
34 | {
35 | "value": "31194",
36 | "label": "campo do brito"
37 | },
38 | {
39 | "value": "31216",
40 | "label": "canhoba"
41 | },
42 | {
43 | "value": "31232",
44 | "label": "canindé de são francisco"
45 | },
46 | {
47 | "value": "31259",
48 | "label": "capela"
49 | },
50 | {
51 | "value": "31275",
52 | "label": "carira"
53 | },
54 | {
55 | "value": "31291",
56 | "label": "carmópolis"
57 | },
58 | {
59 | "value": "31313",
60 | "label": "cedro de são joão"
61 | },
62 | {
63 | "value": "31330",
64 | "label": "cristinápolis"
65 | },
66 | {
67 | "value": "31372",
68 | "label": "cumbe"
69 | },
70 | {
71 | "value": "31399",
72 | "label": "divina pastora"
73 | },
74 | {
75 | "value": "31410",
76 | "label": "estância"
77 | },
78 | {
79 | "value": "31437",
80 | "label": "feira nova"
81 | },
82 | {
83 | "value": "31453",
84 | "label": "frei paulo"
85 | },
86 | {
87 | "value": "31496",
88 | "label": "gararu"
89 | },
90 | {
91 | "value": "31470",
92 | "label": "general maynard"
93 | },
94 | {
95 | "value": "31518",
96 | "label": "graccho cardoso"
97 | },
98 | {
99 | "value": "31534",
100 | "label": "ilha das flores"
101 | },
102 | {
103 | "value": "31550",
104 | "label": "indiaroba"
105 | },
106 | {
107 | "value": "31577",
108 | "label": "itabaiana"
109 | },
110 | {
111 | "value": "31593",
112 | "label": "itabaianinha"
113 | },
114 | {
115 | "value": "31615",
116 | "label": "itabi"
117 | },
118 | {
119 | "value": "31631",
120 | "label": "itaporanga d'ajuda"
121 | },
122 | {
123 | "value": "31658",
124 | "label": "japaratuba"
125 | },
126 | {
127 | "value": "31674",
128 | "label": "japoatã"
129 | },
130 | {
131 | "value": "31690",
132 | "label": "lagarto"
133 | },
134 | {
135 | "value": "31712",
136 | "label": "laranjeiras"
137 | },
138 | {
139 | "value": "31739",
140 | "label": "macambira"
141 | },
142 | {
143 | "value": "31755",
144 | "label": "malhada dos bois"
145 | },
146 | {
147 | "value": "31771",
148 | "label": "malhador"
149 | },
150 | {
151 | "value": "31798",
152 | "label": "maruim"
153 | },
154 | {
155 | "value": "31810",
156 | "label": "moita bonita"
157 | },
158 | {
159 | "value": "31836",
160 | "label": "monte alegre de sergipe"
161 | },
162 | {
163 | "value": "31852",
164 | "label": "muribeca"
165 | },
166 | {
167 | "value": "31879",
168 | "label": "neópolis"
169 | },
170 | {
171 | "value": "31356",
172 | "label": "nossa senhora aparecida"
173 | },
174 | {
175 | "value": "31895",
176 | "label": "nossa senhora da glória"
177 | },
178 | {
179 | "value": "31917",
180 | "label": "nossa senhora das dores"
181 | },
182 | {
183 | "value": "31933",
184 | "label": "nossa senhora de lourdes"
185 | },
186 | {
187 | "value": "31950",
188 | "label": "nossa senhora do socorro"
189 | },
190 | {
191 | "value": "31976",
192 | "label": "pacatuba"
193 | },
194 | {
195 | "value": "31992",
196 | "label": "pedra mole"
197 | },
198 | {
199 | "value": "32018",
200 | "label": "pedrinhas"
201 | },
202 | {
203 | "value": "32034",
204 | "label": "pinhão"
205 | },
206 | {
207 | "value": "32050",
208 | "label": "pirambu"
209 | },
210 | {
211 | "value": "32077",
212 | "label": "poço redondo"
213 | },
214 | {
215 | "value": "32093",
216 | "label": "poço verde"
217 | },
218 | {
219 | "value": "32115",
220 | "label": "porto da folha"
221 | },
222 | {
223 | "value": "32131",
224 | "label": "propriá"
225 | },
226 | {
227 | "value": "32158",
228 | "label": "riachão do dantas"
229 | },
230 | {
231 | "value": "32174",
232 | "label": "riachuelo"
233 | },
234 | {
235 | "value": "32190",
236 | "label": "ribeirópolis"
237 | },
238 | {
239 | "value": "32212",
240 | "label": "rosário do catete"
241 | },
242 | {
243 | "value": "32239",
244 | "label": "salgado"
245 | },
246 | {
247 | "value": "32255",
248 | "label": "santa luzia do itanhy"
249 | },
250 | {
251 | "value": "32298",
252 | "label": "santa rosa de lima"
253 | },
254 | {
255 | "value": "31003",
256 | "label": "santana do são francisco"
257 | },
258 | {
259 | "value": "32310",
260 | "label": "santo amaro das brotas"
261 | },
262 | {
263 | "value": "32336",
264 | "label": "são cristóvão"
265 | },
266 | {
267 | "value": "32352",
268 | "label": "são domingos"
269 | },
270 | {
271 | "value": "32379",
272 | "label": "são francisco"
273 | },
274 | {
275 | "value": "32395",
276 | "label": "são miguel do aleixo"
277 | },
278 | {
279 | "value": "32417",
280 | "label": "simão dias"
281 | },
282 | {
283 | "value": "32433",
284 | "label": "siriri"
285 | },
286 | {
287 | "value": "32450",
288 | "label": "telha"
289 | },
290 | {
291 | "value": "32476",
292 | "label": "tobias barreto"
293 | },
294 | {
295 | "value": "32492",
296 | "label": "tomar do geru"
297 | },
298 | {
299 | "value": "32514",
300 | "label": "umbaúba"
301 | }
302 | ]
--------------------------------------------------------------------------------
/src/data/cities/es.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "56014",
4 | "label": "afonso cláudio"
5 | },
6 | {
7 | "value": "56022",
8 | "label": "água doce do norte"
9 | },
10 | {
11 | "value": "57991",
12 | "label": "águia branca"
13 | },
14 | {
15 | "value": "56030",
16 | "label": "alegre"
17 | },
18 | {
19 | "value": "56057",
20 | "label": "alfredo chaves"
21 | },
22 | {
23 | "value": "56065",
24 | "label": "alto rio novo"
25 | },
26 | {
27 | "value": "56073",
28 | "label": "anchieta"
29 | },
30 | {
31 | "value": "56090",
32 | "label": "apiacá"
33 | },
34 | {
35 | "value": "56111",
36 | "label": "aracruz"
37 | },
38 | {
39 | "value": "56138",
40 | "label": "atílio vivácqua"
41 | },
42 | {
43 | "value": "56154",
44 | "label": "baixo guandu"
45 | },
46 | {
47 | "value": "56170",
48 | "label": "barra de são francisco"
49 | },
50 | {
51 | "value": "56197",
52 | "label": "boa esperança"
53 | },
54 | {
55 | "value": "56219",
56 | "label": "bom jesus do norte"
57 | },
58 | {
59 | "value": "56146",
60 | "label": "brejetuba"
61 | },
62 | {
63 | "value": "56235",
64 | "label": "cachoeiro de itapemirim"
65 | },
66 | {
67 | "value": "56251",
68 | "label": "cariacica"
69 | },
70 | {
71 | "value": "56278",
72 | "label": "castelo"
73 | },
74 | {
75 | "value": "56294",
76 | "label": "colatina"
77 | },
78 | {
79 | "value": "56316",
80 | "label": "conceição da barra"
81 | },
82 | {
83 | "value": "56332",
84 | "label": "conceição do castelo"
85 | },
86 | {
87 | "value": "56359",
88 | "label": "divino de são lourenço"
89 | },
90 | {
91 | "value": "56375",
92 | "label": "domingos martins"
93 | },
94 | {
95 | "value": "56391",
96 | "label": "dores do rio preto"
97 | },
98 | {
99 | "value": "56413",
100 | "label": "ecoporanga"
101 | },
102 | {
103 | "value": "56430",
104 | "label": "fundão"
105 | },
106 | {
107 | "value": "56308",
108 | "label": "governador lindenberg"
109 | },
110 | {
111 | "value": "56456",
112 | "label": "guaçuí"
113 | },
114 | {
115 | "value": "56472",
116 | "label": "guarapari"
117 | },
118 | {
119 | "value": "57096",
120 | "label": "ibatiba"
121 | },
122 | {
123 | "value": "56499",
124 | "label": "ibiraçu"
125 | },
126 | {
127 | "value": "56502",
128 | "label": "ibitirama"
129 | },
130 | {
131 | "value": "56510",
132 | "label": "iconha"
133 | },
134 | {
135 | "value": "56049",
136 | "label": "irupi"
137 | },
138 | {
139 | "value": "56537",
140 | "label": "itaguaçu"
141 | },
142 | {
143 | "value": "56553",
144 | "label": "itapemirim"
145 | },
146 | {
147 | "value": "56570",
148 | "label": "itarana"
149 | },
150 | {
151 | "value": "56596",
152 | "label": "iúna"
153 | },
154 | {
155 | "value": "57134",
156 | "label": "jaguaré"
157 | },
158 | {
159 | "value": "56618",
160 | "label": "jerônimo monteiro"
161 | },
162 | {
163 | "value": "56626",
164 | "label": "joão neiva"
165 | },
166 | {
167 | "value": "57916",
168 | "label": "laranja da terra"
169 | },
170 | {
171 | "value": "56634",
172 | "label": "linhares"
173 | },
174 | {
175 | "value": "56650",
176 | "label": "mantenópolis"
177 | },
178 | {
179 | "value": "56120",
180 | "label": "marataízes"
181 | },
182 | {
183 | "value": "56103",
184 | "label": "marechal floriano"
185 | },
186 | {
187 | "value": "57070",
188 | "label": "marilândia"
189 | },
190 | {
191 | "value": "56677",
192 | "label": "mimoso do sul"
193 | },
194 | {
195 | "value": "56693",
196 | "label": "montanha"
197 | },
198 | {
199 | "value": "56715",
200 | "label": "mucurici"
201 | },
202 | {
203 | "value": "56731",
204 | "label": "muniz freire"
205 | },
206 | {
207 | "value": "56758",
208 | "label": "muqui"
209 | },
210 | {
211 | "value": "56774",
212 | "label": "nova venécia"
213 | },
214 | {
215 | "value": "56790",
216 | "label": "pancas"
217 | },
218 | {
219 | "value": "57150",
220 | "label": "pedro canário"
221 | },
222 | {
223 | "value": "56812",
224 | "label": "pinheiros"
225 | },
226 | {
227 | "value": "56839",
228 | "label": "piúma"
229 | },
230 | {
231 | "value": "56200",
232 | "label": "ponto belo"
233 | },
234 | {
235 | "value": "56855",
236 | "label": "presidente kennedy"
237 | },
238 | {
239 | "value": "57118",
240 | "label": "rio bananal"
241 | },
242 | {
243 | "value": "56871",
244 | "label": "rio novo do sul"
245 | },
246 | {
247 | "value": "56898",
248 | "label": "santa leopoldina"
249 | },
250 | {
251 | "value": "57932",
252 | "label": "santa maria de jetibá"
253 | },
254 | {
255 | "value": "56910",
256 | "label": "santa teresa"
257 | },
258 | {
259 | "value": "56006",
260 | "label": "são domingos do norte"
261 | },
262 | {
263 | "value": "56936",
264 | "label": "são gabriel da palha"
265 | },
266 | {
267 | "value": "56952",
268 | "label": "são josé do calçado"
269 | },
270 | {
271 | "value": "56979",
272 | "label": "são mateus"
273 | },
274 | {
275 | "value": "56162",
276 | "label": "são roque do canaã"
277 | },
278 | {
279 | "value": "56995",
280 | "label": "serra"
281 | },
282 | {
283 | "value": "56189",
284 | "label": "sooretama"
285 | },
286 | {
287 | "value": "57959",
288 | "label": "vargem alta"
289 | },
290 | {
291 | "value": "57975",
292 | "label": "venda nova do imigrante"
293 | },
294 | {
295 | "value": "57010",
296 | "label": "viana"
297 | },
298 | {
299 | "value": "56081",
300 | "label": "vila pavão"
301 | },
302 | {
303 | "value": "56227",
304 | "label": "vila valério"
305 | },
306 | {
307 | "value": "57037",
308 | "label": "vila velha"
309 | },
310 | {
311 | "value": "57053",
312 | "label": "vitória"
313 | }
314 | ]
--------------------------------------------------------------------------------
/src/data/cities/ms.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "90034",
4 | "label": "água clara"
5 | },
6 | {
7 | "value": "55018",
8 | "label": "alcinópolis"
9 | },
10 | {
11 | "value": "90115",
12 | "label": "amambai"
13 | },
14 | {
15 | "value": "90131",
16 | "label": "anastácio"
17 | },
18 | {
19 | "value": "90158",
20 | "label": "anaurilândia"
21 | },
22 | {
23 | "value": "91693",
24 | "label": "angélica"
25 | },
26 | {
27 | "value": "90174",
28 | "label": "antônio joão"
29 | },
30 | {
31 | "value": "90190",
32 | "label": "aparecida do taboado"
33 | },
34 | {
35 | "value": "90212",
36 | "label": "aquidauana"
37 | },
38 | {
39 | "value": "91715",
40 | "label": "aral moreira"
41 | },
42 | {
43 | "value": "90298",
44 | "label": "bandeirantes"
45 | },
46 | {
47 | "value": "90379",
48 | "label": "bataguassu"
49 | },
50 | {
51 | "value": "90395",
52 | "label": "batayporã"
53 | },
54 | {
55 | "value": "90417",
56 | "label": "bela vista"
57 | },
58 | {
59 | "value": "98019",
60 | "label": "bodoquena"
61 | },
62 | {
63 | "value": "90433",
64 | "label": "bonito"
65 | },
66 | {
67 | "value": "90450",
68 | "label": "brasilândia"
69 | },
70 | {
71 | "value": "90557",
72 | "label": "caarapó"
73 | },
74 | {
75 | "value": "90492",
76 | "label": "camapuã"
77 | },
78 | {
79 | "value": "90514",
80 | "label": "campo grande"
81 | },
82 | {
83 | "value": "90530",
84 | "label": "caracol"
85 | },
86 | {
87 | "value": "90573",
88 | "label": "cassilândia"
89 | },
90 | {
91 | "value": "91782",
92 | "label": "chapadão do sul"
93 | },
94 | {
95 | "value": "90611",
96 | "label": "corguinho"
97 | },
98 | {
99 | "value": "98590",
100 | "label": "coronel sapucaia"
101 | },
102 | {
103 | "value": "90638",
104 | "label": "corumbá"
105 | },
106 | {
107 | "value": "98035",
108 | "label": "costa rica"
109 | },
110 | {
111 | "value": "90654",
112 | "label": "coxim"
113 | },
114 | {
115 | "value": "91758",
116 | "label": "deodápolis"
117 | },
118 | {
119 | "value": "91804",
120 | "label": "dois irmãos do buriti"
121 | },
122 | {
123 | "value": "98051",
124 | "label": "douradina"
125 | },
126 | {
127 | "value": "90735",
128 | "label": "dourados"
129 | },
130 | {
131 | "value": "91731",
132 | "label": "eldorado"
133 | },
134 | {
135 | "value": "90751",
136 | "label": "fátima do sul"
137 | },
138 | {
139 | "value": "55069",
140 | "label": "figueirão"
141 | },
142 | {
143 | "value": "90794",
144 | "label": "glória de dourados"
145 | },
146 | {
147 | "value": "90816",
148 | "label": "guia lopes da laguna"
149 | },
150 | {
151 | "value": "90859",
152 | "label": "iguatemi"
153 | },
154 | {
155 | "value": "90875",
156 | "label": "inocência"
157 | },
158 | {
159 | "value": "90891",
160 | "label": "itaporã"
161 | },
162 | {
163 | "value": "98078",
164 | "label": "itaquiraí"
165 | },
166 | {
167 | "value": "90930",
168 | "label": "ivinhema"
169 | },
170 | {
171 | "value": "55034",
172 | "label": "japorã"
173 | },
174 | {
175 | "value": "90972",
176 | "label": "jaraguari"
177 | },
178 | {
179 | "value": "90999",
180 | "label": "jardim"
181 | },
182 | {
183 | "value": "91014",
184 | "label": "jateí"
185 | },
186 | {
187 | "value": "91820",
188 | "label": "juti"
189 | },
190 | {
191 | "value": "91030",
192 | "label": "ladário"
193 | },
194 | {
195 | "value": "55026",
196 | "label": "laguna carapã"
197 | },
198 | {
199 | "value": "91073",
200 | "label": "maracaju"
201 | },
202 | {
203 | "value": "91111",
204 | "label": "miranda"
205 | },
206 | {
207 | "value": "91790",
208 | "label": "mundo novo"
209 | },
210 | {
211 | "value": "91138",
212 | "label": "naviraí"
213 | },
214 | {
215 | "value": "91154",
216 | "label": "nioaque"
217 | },
218 | {
219 | "value": "55000",
220 | "label": "nova alvorada do sul"
221 | },
222 | {
223 | "value": "91235",
224 | "label": "nova andradina"
225 | },
226 | {
227 | "value": "55042",
228 | "label": "novo horizonte do sul"
229 | },
230 | {
231 | "value": "55050",
232 | "label": "paraíso das águas"
233 | },
234 | {
235 | "value": "91251",
236 | "label": "paranaíba"
237 | },
238 | {
239 | "value": "91847",
240 | "label": "paranhos"
241 | },
242 | {
243 | "value": "91278",
244 | "label": "pedro gomes"
245 | },
246 | {
247 | "value": "91316",
248 | "label": "ponta porã"
249 | },
250 | {
251 | "value": "91375",
252 | "label": "porto murtinho"
253 | },
254 | {
255 | "value": "91413",
256 | "label": "ribas do rio pardo"
257 | },
258 | {
259 | "value": "91430",
260 | "label": "rio brilhante"
261 | },
262 | {
263 | "value": "91456",
264 | "label": "rio negro"
265 | },
266 | {
267 | "value": "91472",
268 | "label": "rio verde de mato grosso"
269 | },
270 | {
271 | "value": "91499",
272 | "label": "rochedo"
273 | },
274 | {
275 | "value": "91863",
276 | "label": "santa rita do pardo"
277 | },
278 | {
279 | "value": "98094",
280 | "label": "são gabriel do oeste"
281 | },
282 | {
283 | "value": "98116",
284 | "label": "selvíria"
285 | },
286 | {
287 | "value": "98132",
288 | "label": "sete quedas"
289 | },
290 | {
291 | "value": "91570",
292 | "label": "sidrolândia"
293 | },
294 | {
295 | "value": "91880",
296 | "label": "sonora"
297 | },
298 | {
299 | "value": "98159",
300 | "label": "tacuru"
301 | },
302 | {
303 | "value": "98175",
304 | "label": "taquarussu"
305 | },
306 | {
307 | "value": "91596",
308 | "label": "terenos"
309 | },
310 | {
311 | "value": "91650",
312 | "label": "três lagoas"
313 | },
314 | {
315 | "value": "91901",
316 | "label": "vicentina"
317 | }
318 | ]
--------------------------------------------------------------------------------
/src/data/cities/rj.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "58017",
4 | "label": "angra dos reis"
5 | },
6 | {
7 | "value": "58181",
8 | "label": "aperibé"
9 | },
10 | {
11 | "value": "58033",
12 | "label": "araruama"
13 | },
14 | {
15 | "value": "58220",
16 | "label": "areal"
17 | },
18 | {
19 | "value": "58408",
20 | "label": "armação dos búzios"
21 | },
22 | {
23 | "value": "59277",
24 | "label": "arraial do cabo"
25 | },
26 | {
27 | "value": "58050",
28 | "label": "barra do piraí"
29 | },
30 | {
31 | "value": "58076",
32 | "label": "barra mansa"
33 | },
34 | {
35 | "value": "58041",
36 | "label": "belford roxo"
37 | },
38 | {
39 | "value": "58092",
40 | "label": "bom jardim"
41 | },
42 | {
43 | "value": "58114",
44 | "label": "bom jesus do itabapoana"
45 | },
46 | {
47 | "value": "58130",
48 | "label": "cabo frio"
49 | },
50 | {
51 | "value": "58157",
52 | "label": "cachoeiras de macacu"
53 | },
54 | {
55 | "value": "58173",
56 | "label": "cambuci"
57 | },
58 | {
59 | "value": "58190",
60 | "label": "campos dos goytacazes"
61 | },
62 | {
63 | "value": "58211",
64 | "label": "cantagalo"
65 | },
66 | {
67 | "value": "58300",
68 | "label": "carapebus"
69 | },
70 | {
71 | "value": "58068",
72 | "label": "cardoso moreira"
73 | },
74 | {
75 | "value": "58238",
76 | "label": "carmo"
77 | },
78 | {
79 | "value": "58254",
80 | "label": "casimiro de abreu"
81 | },
82 | {
83 | "value": "58165",
84 | "label": "comendador levy gasparian"
85 | },
86 | {
87 | "value": "58270",
88 | "label": "conceição de macabu"
89 | },
90 | {
91 | "value": "58297",
92 | "label": "cordeiro"
93 | },
94 | {
95 | "value": "58319",
96 | "label": "duas barras"
97 | },
98 | {
99 | "value": "58335",
100 | "label": "duque de caxias"
101 | },
102 | {
103 | "value": "58351",
104 | "label": "engenheiro paulo de frontin"
105 | },
106 | {
107 | "value": "58106",
108 | "label": "guapimirim"
109 | },
110 | {
111 | "value": "58262",
112 | "label": "iguaba grande"
113 | },
114 | {
115 | "value": "58378",
116 | "label": "itaboraí"
117 | },
118 | {
119 | "value": "58394",
120 | "label": "itaguaí"
121 | },
122 | {
123 | "value": "59293",
124 | "label": "italva"
125 | },
126 | {
127 | "value": "58416",
128 | "label": "itaocara"
129 | },
130 | {
131 | "value": "58432",
132 | "label": "itaperuna"
133 | },
134 | {
135 | "value": "58440",
136 | "label": "itatiaia"
137 | },
138 | {
139 | "value": "58149",
140 | "label": "japeri"
141 | },
142 | {
143 | "value": "58459",
144 | "label": "laje do muriaé"
145 | },
146 | {
147 | "value": "58475",
148 | "label": "macaé"
149 | },
150 | {
151 | "value": "58386",
152 | "label": "macuco"
153 | },
154 | {
155 | "value": "58491",
156 | "label": "magé"
157 | },
158 | {
159 | "value": "58513",
160 | "label": "mangaratiba"
161 | },
162 | {
163 | "value": "58530",
164 | "label": "maricá"
165 | },
166 | {
167 | "value": "58556",
168 | "label": "mendes"
169 | },
170 | {
171 | "value": "58467",
172 | "label": "mesquita"
173 | },
174 | {
175 | "value": "58572",
176 | "label": "miguel pereira"
177 | },
178 | {
179 | "value": "58599",
180 | "label": "miracema"
181 | },
182 | {
183 | "value": "58610",
184 | "label": "natividade"
185 | },
186 | {
187 | "value": "58637",
188 | "label": "nilópolis"
189 | },
190 | {
191 | "value": "58653",
192 | "label": "niterói"
193 | },
194 | {
195 | "value": "58670",
196 | "label": "nova friburgo"
197 | },
198 | {
199 | "value": "58696",
200 | "label": "nova iguaçu"
201 | },
202 | {
203 | "value": "58718",
204 | "label": "paracambi"
205 | },
206 | {
207 | "value": "58734",
208 | "label": "paraíba do sul"
209 | },
210 | {
211 | "value": "58750",
212 | "label": "paraty"
213 | },
214 | {
215 | "value": "59315",
216 | "label": "paty do alferes"
217 | },
218 | {
219 | "value": "58777",
220 | "label": "petrópolis"
221 | },
222 | {
223 | "value": "58246",
224 | "label": "pinheiral"
225 | },
226 | {
227 | "value": "58793",
228 | "label": "piraí"
229 | },
230 | {
231 | "value": "58815",
232 | "label": "porciúncula"
233 | },
234 | {
235 | "value": "58327",
236 | "label": "porto real"
237 | },
238 | {
239 | "value": "58025",
240 | "label": "quatis"
241 | },
242 | {
243 | "value": "58122",
244 | "label": "queimados"
245 | },
246 | {
247 | "value": "58009",
248 | "label": "quissamã"
249 | },
250 | {
251 | "value": "58831",
252 | "label": "resende"
253 | },
254 | {
255 | "value": "58858",
256 | "label": "rio bonito"
257 | },
258 | {
259 | "value": "58874",
260 | "label": "rio claro"
261 | },
262 | {
263 | "value": "58890",
264 | "label": "rio das flores"
265 | },
266 | {
267 | "value": "58203",
268 | "label": "rio das ostras"
269 | },
270 | {
271 | "value": "60011",
272 | "label": "rio de janeiro"
273 | },
274 | {
275 | "value": "58912",
276 | "label": "santa maria madalena"
277 | },
278 | {
279 | "value": "58939",
280 | "label": "santo antônio de pádua"
281 | },
282 | {
283 | "value": "58955",
284 | "label": "são fidélis"
285 | },
286 | {
287 | "value": "58289",
288 | "label": "são francisco de itabapoana"
289 | },
290 | {
291 | "value": "58971",
292 | "label": "são gonçalo"
293 | },
294 | {
295 | "value": "58998",
296 | "label": "são joão da barra"
297 | },
298 | {
299 | "value": "59013",
300 | "label": "são joão de meriti"
301 | },
302 | {
303 | "value": "58343",
304 | "label": "são josé de ubá"
305 | },
306 | {
307 | "value": "59331",
308 | "label": "são josé do vale do rio preto"
309 | },
310 | {
311 | "value": "59030",
312 | "label": "são pedro da aldeia"
313 | },
314 | {
315 | "value": "59056",
316 | "label": "são sebastião do alto"
317 | },
318 | {
319 | "value": "59072",
320 | "label": "sapucaia"
321 | },
322 | {
323 | "value": "59099",
324 | "label": "saquarema"
325 | },
326 | {
327 | "value": "58424",
328 | "label": "seropédica"
329 | },
330 | {
331 | "value": "59110",
332 | "label": "silva jardim"
333 | },
334 | {
335 | "value": "59137",
336 | "label": "sumidouro"
337 | },
338 | {
339 | "value": "58360",
340 | "label": "tanguá"
341 | },
342 | {
343 | "value": "59153",
344 | "label": "teresópolis"
345 | },
346 | {
347 | "value": "59170",
348 | "label": "trajano de moraes"
349 | },
350 | {
351 | "value": "59196",
352 | "label": "três rios"
353 | },
354 | {
355 | "value": "59218",
356 | "label": "valença"
357 | },
358 | {
359 | "value": "58084",
360 | "label": "varre-sai"
361 | },
362 | {
363 | "value": "59234",
364 | "label": "vassouras"
365 | },
366 | {
367 | "value": "59250",
368 | "label": "volta redonda"
369 | }
370 | ]
--------------------------------------------------------------------------------
/src/data/cities/al.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "27014",
4 | "label": "água branca"
5 | },
6 | {
7 | "value": "27030",
8 | "label": "anadia"
9 | },
10 | {
11 | "value": "27057",
12 | "label": "arapiraca"
13 | },
14 | {
15 | "value": "27073",
16 | "label": "atalaia"
17 | },
18 | {
19 | "value": "27090",
20 | "label": "barra de santo antônio"
21 | },
22 | {
23 | "value": "27111",
24 | "label": "barra de são miguel"
25 | },
26 | {
27 | "value": "27138",
28 | "label": "batalha"
29 | },
30 | {
31 | "value": "27154",
32 | "label": "belém"
33 | },
34 | {
35 | "value": "27170",
36 | "label": "belo monte"
37 | },
38 | {
39 | "value": "27197",
40 | "label": "boca da mata"
41 | },
42 | {
43 | "value": "27219",
44 | "label": "branquinha"
45 | },
46 | {
47 | "value": "27235",
48 | "label": "cacimbinhas"
49 | },
50 | {
51 | "value": "27251",
52 | "label": "cajueiro"
53 | },
54 | {
55 | "value": "27081",
56 | "label": "campestre"
57 | },
58 | {
59 | "value": "27278",
60 | "label": "campo alegre"
61 | },
62 | {
63 | "value": "27294",
64 | "label": "campo grande"
65 | },
66 | {
67 | "value": "27316",
68 | "label": "canapi"
69 | },
70 | {
71 | "value": "27332",
72 | "label": "capela"
73 | },
74 | {
75 | "value": "27359",
76 | "label": "carneiros"
77 | },
78 | {
79 | "value": "27375",
80 | "label": "chã preta"
81 | },
82 | {
83 | "value": "27391",
84 | "label": "coité do nóia"
85 | },
86 | {
87 | "value": "27413",
88 | "label": "colônia leopoldina"
89 | },
90 | {
91 | "value": "27430",
92 | "label": "coqueiro seco"
93 | },
94 | {
95 | "value": "27456",
96 | "label": "coruripe"
97 | },
98 | {
99 | "value": "28894",
100 | "label": "craíbas"
101 | },
102 | {
103 | "value": "27472",
104 | "label": "delmiro gouveia"
105 | },
106 | {
107 | "value": "27499",
108 | "label": "dois riachos"
109 | },
110 | {
111 | "value": "27049",
112 | "label": "estrela de alagoas"
113 | },
114 | {
115 | "value": "27510",
116 | "label": "feira grande"
117 | },
118 | {
119 | "value": "27537",
120 | "label": "feliz deserto"
121 | },
122 | {
123 | "value": "27553",
124 | "label": "flexeiras"
125 | },
126 | {
127 | "value": "27570",
128 | "label": "girau do ponciano"
129 | },
130 | {
131 | "value": "27596",
132 | "label": "ibateguara"
133 | },
134 | {
135 | "value": "27618",
136 | "label": "igaci"
137 | },
138 | {
139 | "value": "27634",
140 | "label": "igreja nova"
141 | },
142 | {
143 | "value": "27650",
144 | "label": "inhapi"
145 | },
146 | {
147 | "value": "27677",
148 | "label": "jacaré dos homens"
149 | },
150 | {
151 | "value": "27693",
152 | "label": "jacuípe"
153 | },
154 | {
155 | "value": "27715",
156 | "label": "japaratinga"
157 | },
158 | {
159 | "value": "27731",
160 | "label": "jaramataia"
161 | },
162 | {
163 | "value": "27065",
164 | "label": "jequiá da praia"
165 | },
166 | {
167 | "value": "27758",
168 | "label": "joaquim gomes"
169 | },
170 | {
171 | "value": "27774",
172 | "label": "jundiá"
173 | },
174 | {
175 | "value": "27790",
176 | "label": "junqueiro"
177 | },
178 | {
179 | "value": "27812",
180 | "label": "lagoa da canoa"
181 | },
182 | {
183 | "value": "27839",
184 | "label": "limoeiro de anadia"
185 | },
186 | {
187 | "value": "27855",
188 | "label": "maceió"
189 | },
190 | {
191 | "value": "27871",
192 | "label": "major isidoro"
193 | },
194 | {
195 | "value": "27979",
196 | "label": "mar vermelho"
197 | },
198 | {
199 | "value": "27898",
200 | "label": "maragogi"
201 | },
202 | {
203 | "value": "27910",
204 | "label": "maravilha"
205 | },
206 | {
207 | "value": "27936",
208 | "label": "marechal deodoro"
209 | },
210 | {
211 | "value": "27952",
212 | "label": "maribondo"
213 | },
214 | {
215 | "value": "27995",
216 | "label": "mata grande"
217 | },
218 | {
219 | "value": "28010",
220 | "label": "matriz de camaragibe"
221 | },
222 | {
223 | "value": "28037",
224 | "label": "messias"
225 | },
226 | {
227 | "value": "28053",
228 | "label": "minador do negrão"
229 | },
230 | {
231 | "value": "28070",
232 | "label": "monteirópolis"
233 | },
234 | {
235 | "value": "28096",
236 | "label": "murici"
237 | },
238 | {
239 | "value": "28118",
240 | "label": "novo lino"
241 | },
242 | {
243 | "value": "28134",
244 | "label": "olho d'água das flores"
245 | },
246 | {
247 | "value": "28150",
248 | "label": "olho d'água do casado"
249 | },
250 | {
251 | "value": "28177",
252 | "label": "olho d'água grande"
253 | },
254 | {
255 | "value": "28193",
256 | "label": "olivença"
257 | },
258 | {
259 | "value": "28215",
260 | "label": "ouro branco"
261 | },
262 | {
263 | "value": "28231",
264 | "label": "palestina"
265 | },
266 | {
267 | "value": "28258",
268 | "label": "palmeira dos índios"
269 | },
270 | {
271 | "value": "28274",
272 | "label": "pão de açúcar"
273 | },
274 | {
275 | "value": "27022",
276 | "label": "pariconha"
277 | },
278 | {
279 | "value": "27006",
280 | "label": "paripueira"
281 | },
282 | {
283 | "value": "28290",
284 | "label": "passo de camaragibe"
285 | },
286 | {
287 | "value": "28312",
288 | "label": "paulo jacinto"
289 | },
290 | {
291 | "value": "28339",
292 | "label": "penedo"
293 | },
294 | {
295 | "value": "28355",
296 | "label": "piaçabuçu"
297 | },
298 | {
299 | "value": "28371",
300 | "label": "pilar"
301 | },
302 | {
303 | "value": "28398",
304 | "label": "pindoba"
305 | },
306 | {
307 | "value": "28410",
308 | "label": "piranhas"
309 | },
310 | {
311 | "value": "28436",
312 | "label": "poço das trincheiras"
313 | },
314 | {
315 | "value": "28452",
316 | "label": "porto calvo"
317 | },
318 | {
319 | "value": "28479",
320 | "label": "porto de pedras"
321 | },
322 | {
323 | "value": "28495",
324 | "label": "porto real do colégio"
325 | },
326 | {
327 | "value": "28517",
328 | "label": "quebrangulo"
329 | },
330 | {
331 | "value": "28533",
332 | "label": "rio largo"
333 | },
334 | {
335 | "value": "28550",
336 | "label": "roteiro"
337 | },
338 | {
339 | "value": "28576",
340 | "label": "santa luzia do norte"
341 | },
342 | {
343 | "value": "28592",
344 | "label": "santana do ipanema"
345 | },
346 | {
347 | "value": "28614",
348 | "label": "santana do mundaú"
349 | },
350 | {
351 | "value": "28630",
352 | "label": "são brás"
353 | },
354 | {
355 | "value": "28657",
356 | "label": "são josé da laje"
357 | },
358 | {
359 | "value": "28673",
360 | "label": "são josé da tapera"
361 | },
362 | {
363 | "value": "28690",
364 | "label": "são luís do quitunde"
365 | },
366 | {
367 | "value": "28711",
368 | "label": "são miguel dos campos"
369 | },
370 | {
371 | "value": "28738",
372 | "label": "são miguel dos milagres"
373 | },
374 | {
375 | "value": "28754",
376 | "label": "são sebastião"
377 | },
378 | {
379 | "value": "28770",
380 | "label": "satuba"
381 | },
382 | {
383 | "value": "28916",
384 | "label": "senador rui palmeira"
385 | },
386 | {
387 | "value": "28797",
388 | "label": "tanque d'arca"
389 | },
390 | {
391 | "value": "28819",
392 | "label": "taquarana"
393 | },
394 | {
395 | "value": "28932",
396 | "label": "teotônio vilela"
397 | },
398 | {
399 | "value": "28835",
400 | "label": "traipu"
401 | },
402 | {
403 | "value": "28851",
404 | "label": "união dos palmares"
405 | },
406 | {
407 | "value": "28878",
408 | "label": "viçosa"
409 | }
410 | ]
--------------------------------------------------------------------------------
/src/data/mock-candidato.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 240001918430,
3 | "nomeUrna": "GILSON MARCOS KUHN",
4 | "numero": 30,
5 | "idCandidatoSuperior": 0,
6 | "nomeCompleto": "GILSON MARCOS KUHN",
7 | "descricaoSexo": "MASC.",
8 | "dataDeNascimento": "1978-10-13",
9 | "tituloEleitor": "033152040973",
10 | "cpf": "02193395977",
11 | "descricaoEstadoCivil": "Divorciado(a)",
12 | "descricaoCorRaca": "BRANCA",
13 | "descricaoSituacao": "Aguardando julgamento",
14 | "nacionalidade": "Brasileira nata",
15 | "grauInstrucao": "Superior incompleto",
16 | "ocupacao": "Empresário",
17 | "gastoCampanha1T": 159850.76,
18 | "gastoCampanha2T": 0,
19 | "sgUfNascimento": "SC",
20 | "nomeMunicipioNascimento": "TREZE TÍLIAS",
21 | "localCandidatura": "LUZERNA",
22 | "ufCandidatura": "81809",
23 | "ufSuperiorCandidatura": "SC",
24 | "codigoSituacaoCandidatoSuperior": 1,
25 | "dataUltimaAtualizacao": "2024-08-10 11:32",
26 | "fotoUrl": "https://divulgacandcontas.tse.jus.br/divulga/rest/arquivo/img/2045202024/240001918430/81809",
27 | "fotoUrlPublicavel": true,
28 | "fotoDataUltimaAtualizacao": null,
29 | "descricaoTotalizacao": "Concorrendo",
30 | "nomeColigacao": "NOVO",
31 | "composicaoColigacao": "**",
32 | "descricaoTipoDrap": "Partido Isolado",
33 | "numeroProcessoDrap": "06000839520246240018",
34 | "numeroProcessoDrapEncrypt": "ffdc9f41b8e566c5d5debcd0d6f8f2c0475f81ca4e12f11c220b316d13e5f47242e168fab4de9ba8",
35 | "numeroProcesso": "06000848020246240018",
36 | "numeroProcessoEncrypt": "974313b03440fcd0a956235ce18373bb475f81ca4e12f11c220b316d13e5f47242e168fab4de9ba8",
37 | "numeroProcessoPrestContas": null,
38 | "numeroProcessoPrestContasEncrypt": null,
39 | "numeroProtocolo": null,
40 | "cargo": {
41 | "codigo": 11,
42 | "sigla": null,
43 | "nome": "Prefeito",
44 | "codSuperior": 0,
45 | "titular": true,
46 | "contagem": 0
47 | },
48 | "bens": [
49 | {
50 | "ordem": 1,
51 | "descricao": "moto esportiva gsr 1000 ano 2001",
52 | "descricaoDeTipoDeBem": "Veículo automotor terrestre: caminhão, automóvel, moto, etc.",
53 | "valor": 30000,
54 | "dataUltimaAtualizacao": "2024-08-01"
55 | },
56 | {
57 | "ordem": 2,
58 | "descricao": "camionete montana ano 2005",
59 | "descricaoDeTipoDeBem": "Veículo automotor terrestre: caminhão, automóvel, moto, etc.",
60 | "valor": 35000,
61 | "dataUltimaAtualizacao": "2024-08-01"
62 | },
63 | {
64 | "ordem": 3,
65 | "descricao": "fábrica de móveis planejados",
66 | "descricaoDeTipoDeBem": "Loja",
67 | "valor": 60000,
68 | "dataUltimaAtualizacao": "2024-08-01"
69 | }
70 | ],
71 | "totalDeBens": 125000,
72 | "vices": [
73 | {
74 | "DT_ULTIMA_ATUALIZACAO": "2024-08-10",
75 | "nomeColigacao": null,
76 | "composicaoColigacao": null,
77 | "stRegistro": null,
78 | "situacaoCandidato": null,
79 | "codigoSituacaoCandidatoSuperior": 1,
80 | "urlFoto": "https://divulgacandcontas.tse.jus.br/divulga/rest/arquivo/img/2045202024/240001918431/81809",
81 | "urlFotoPublicavel": true,
82 | "generoPublicavel": false,
83 | "orientacaoSexualPublicavel": false,
84 | "sq_CANDIDATO": 240001918431,
85 | "sg_UE": "81809",
86 | "dt_ULTIMA_ATUALIZACAO": 1723300401000,
87 | "sq_CANDIDATO_SUPERIOR": null,
88 | "nr_CANDIDATO": "30",
89 | "nm_URNA": "SILVESTRE",
90 | "nm_CANDIDATO": "SILVESTRE ETGES",
91 | "ds_CARGO": "Vice-prefeito",
92 | "nm_PARTIDO": "Partido Novo",
93 | "sg_PARTIDO": "NOVO",
94 | "sq_ELEICAO": 2045202024,
95 | "candidatoApto": false
96 | }
97 | ],
98 | "partido": {
99 | "numero": 30,
100 | "sigla": "NOVO",
101 | "nome": "Partido Novo",
102 | "sqPrestadorConta": null
103 | },
104 | "eleicao": {
105 | "id": 2045202024,
106 | "siglaUF": null,
107 | "localidadeSgUe": null,
108 | "ano": 2024,
109 | "codigo": null,
110 | "nomeEleicao": null,
111 | "tipoEleicao": null,
112 | "turno": null,
113 | "tipoAbrangencia": null,
114 | "dataEleicao": null,
115 | "codSituacaoEleicao": null,
116 | "descricaoSituacaoEleicao": null,
117 | "descricaoEleicao": "2024"
118 | },
119 | "emails": [
120 | "kgilson.marcos@hotmail.com"
121 | ],
122 | "sites": [
123 | "https://www.instagram.com/kuhngilson?igsh=NnlnbDZmcDNjdGZ&utm_source=qr",
124 | "https://www.facebook.com/gilsonkuhn.1?mibextid=LQQJd4"
125 | ],
126 | "arquivos": [
127 | {
128 | "idArquivo": 240012138122,
129 | "nome": "certidocriminaldajustiafederalde1grau.pdf",
130 | "url": "candidaturas/oficial/2024/SC/81809/619/candidatos/1034961/",
131 | "tipo": "pdf",
132 | "codTipo": "11",
133 | "fullFilePath": null,
134 | "fileInputStream": null,
135 | "fileByteArray": null
136 | },
137 | {
138 | "idArquivo": 240012138121,
139 | "nome": "propostadegoverno.pdf",
140 | "url": "candidaturas/oficial/2024/SC/81809/619/candidatos/1034961/",
141 | "tipo": "pdf",
142 | "codTipo": "5",
143 | "fullFilePath": null,
144 | "fileInputStream": null,
145 | "fileByteArray": null
146 | },
147 | {
148 | "idArquivo": 240012138115,
149 | "nome": "certidocriminaldajustiaestadualde2grau.pdf",
150 | "url": "candidaturas/oficial/2024/SC/81809/619/candidatos/1034961/",
151 | "tipo": "pdf",
152 | "codTipo": "14",
153 | "fullFilePath": null,
154 | "fileInputStream": null,
155 | "fileByteArray": null
156 | },
157 | {
158 | "idArquivo": 240012138114,
159 | "nome": "certidocriminaldajustiaestadualde1grau.pdf",
160 | "url": "candidaturas/oficial/2024/SC/81809/619/candidatos/1034961/",
161 | "tipo": "pdf",
162 | "codTipo": "13",
163 | "fullFilePath": null,
164 | "fileInputStream": null,
165 | "fileByteArray": null
166 | },
167 | {
168 | "idArquivo": 240012136434,
169 | "nome": "apicand_certidao_criminal_justica_federal_segundo_grau_1722531641168.pdf",
170 | "url": "candidaturas/oficial/2024/SC/81809/619/candidatos/240001918430/",
171 | "tipo": "pdf",
172 | "codTipo": "12",
173 | "fullFilePath": null,
174 | "fileInputStream": null,
175 | "fileByteArray": null
176 | },
177 | {
178 | "idArquivo": 240012136209,
179 | "nome": "apicand_certidao_criminal_justica_federal_primeiro_grau_1722531638010.pdf",
180 | "url": "candidaturas/oficial/2024/SC/81809/619/candidatos/240001918430/",
181 | "tipo": "pdf",
182 | "codTipo": "11",
183 | "fullFilePath": null,
184 | "fileInputStream": null,
185 | "fileByteArray": null
186 | }
187 | ],
188 | "eleicoesAnteriores": [
189 | {
190 | "nrAno": 2024,
191 | "id": "240001918430",
192 | "nomeUrna": "GILSON MARCOS KUHN",
193 | "nomeCandidato": "GILSON MARCOS KUHN",
194 | "idEleicao": "2045202024",
195 | "sgUe": "81809",
196 | "local": "LUZERNA",
197 | "cargo": "Prefeito",
198 | "partido": "NOVO",
199 | "situacaoTotalizacao": "Concorrendo",
200 | "txLink": "https://divulgacandcontas.tse.jus.br/divulga/#/candidato/2024/2045202024/81809/240001918430"
201 | }
202 | ],
203 | "substituto": null,
204 | "motivos": null,
205 | "motivoSituacao": null,
206 | "codigoSituacaoCandidato": 8,
207 | "descricaoSituacaoCandidato": "Cadastrado",
208 | "isCandidatoInapto": false,
209 | "codigoSituacaoPartido": "A",
210 | "descricaoSituacaoPartido": "Aguardando julgamento",
211 | "isCandFechado": false,
212 | "infoComplementar": {
213 | "generoPublicavel": false,
214 | "orientacaoSexualPublicavel": true,
215 | "identidadeGenero": "Cisgênero",
216 | "orientacaoSexual": "Heterossexual",
217 | "dsTipoEtniaIndigena": null,
218 | "quilombola": "Não",
219 | "nmEncarregadoDados": "PARTIDO NOVO",
220 | "txCanalComunicacao": "lgpd@novo.org.br",
221 | "tpEncarregadoDados": "Pessoa Jurídica"
222 | },
223 | "cdSituacaoCassacao": 0,
224 | "cdSituacaoDiploma": 0,
225 | "legenda": {
226 | "sgUeSuperior": null,
227 | "sgUe": null,
228 | "sqDrap": null,
229 | "nomeLegenda": null,
230 | "legenda": null,
231 | "tpPartido": null,
232 | "telefones": null,
233 | "emails": null,
234 | "nmEncarregadoDados": "PARTIDO NOVO",
235 | "txCanalComunicacao": "lgpd@novo.org.br",
236 | "tpEncarregadoDados": "Pessoa Jurídica"
237 | },
238 | "descricaoNaturalidade": "SC-TREZE TÍLIAS",
239 | "candidatoApto": false,
240 | "cnpjcampanha": "56204552000176",
241 | "gastoCampanha": 0,
242 | "st_MOTIVO_GASTO_ILICITO": false,
243 | "ds_MOTIVO_OUTROS": null,
244 | "st_MOTIVO_AUSENCIA_REQUISITO": false,
245 | "st_MOTIVO_IND_PARTIDO": false,
246 | "st_DIVULGA": true,
247 | "st_DIVULGA_BENS": true,
248 | "st_REELEICAO": false,
249 | "st_DIVULGA_ARQUIVOS": true,
250 | "st_SUBSTITUIDO": false,
251 | "st_MOTIVO_FICHA_LIMPA": false,
252 | "st_MOTIVO_ABUSO_PODER": false,
253 | "st_MOTIVO_COMPRA_VOTO": false,
254 | "st_MOTIVO_CONDUTA_VEDADA": false
255 | }
--------------------------------------------------------------------------------
/src/data/cities/to.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "73008",
4 | "label": "abreulândia"
5 | },
6 | {
7 | "value": "73512",
8 | "label": "aguiarnópolis"
9 | },
10 | {
11 | "value": "96954",
12 | "label": "aliança do tocantins"
13 | },
14 | {
15 | "value": "92070",
16 | "label": "almas"
17 | },
18 | {
19 | "value": "92134",
20 | "label": "alvorada"
21 | },
22 | {
23 | "value": "92193",
24 | "label": "ananás"
25 | },
26 | {
27 | "value": "73075",
28 | "label": "angico"
29 | },
30 | {
31 | "value": "96970",
32 | "label": "aparecida do rio negro"
33 | },
34 | {
35 | "value": "73334",
36 | "label": "aragominas"
37 | },
38 | {
39 | "value": "92371",
40 | "label": "araguacema"
41 | },
42 | {
43 | "value": "92398",
44 | "label": "araguaçu"
45 | },
46 | {
47 | "value": "92410",
48 | "label": "araguaína"
49 | },
50 | {
51 | "value": "73318",
52 | "label": "araguanã"
53 | },
54 | {
55 | "value": "92436",
56 | "label": "araguatins"
57 | },
58 | {
59 | "value": "92452",
60 | "label": "arapoema"
61 | },
62 | {
63 | "value": "92479",
64 | "label": "arraias"
65 | },
66 | {
67 | "value": "96857",
68 | "label": "augustinópolis"
69 | },
70 | {
71 | "value": "92533",
72 | "label": "aurora do tocantins"
73 | },
74 | {
75 | "value": "92576",
76 | "label": "axixá do tocantins"
77 | },
78 | {
79 | "value": "92592",
80 | "label": "babaçulândia"
81 | },
82 | {
83 | "value": "73580",
84 | "label": "bandeirantes do tocantins"
85 | },
86 | {
87 | "value": "73610",
88 | "label": "barra do ouro"
89 | },
90 | {
91 | "value": "96997",
92 | "label": "barrolândia"
93 | },
94 | {
95 | "value": "92002",
96 | "label": "bernardo sayão"
97 | },
98 | {
99 | "value": "73121",
100 | "label": "bom jesus do tocantins"
101 | },
102 | {
103 | "value": "73245",
104 | "label": "brasilândia do tocantins"
105 | },
106 | {
107 | "value": "92738",
108 | "label": "brejinho de nazaré"
109 | },
110 | {
111 | "value": "92045",
112 | "label": "buriti do tocantins"
113 | },
114 | {
115 | "value": "73067",
116 | "label": "cachoeirinha"
117 | },
118 | {
119 | "value": "73091",
120 | "label": "campos lindos"
121 | },
122 | {
123 | "value": "73300",
124 | "label": "cariri do tocantins"
125 | },
126 | {
127 | "value": "73326",
128 | "label": "carmolândia"
129 | },
130 | {
131 | "value": "73423",
132 | "label": "carrasco bonito"
133 | },
134 | {
135 | "value": "92088",
136 | "label": "caseara"
137 | },
138 | {
139 | "value": "73210",
140 | "label": "centenário"
141 | },
142 | {
143 | "value": "73482",
144 | "label": "chapada da natividade"
145 | },
146 | {
147 | "value": "73474",
148 | "label": "chapada de areia"
149 | },
150 | {
151 | "value": "93114",
152 | "label": "colinas do tocantins"
153 | },
154 | {
155 | "value": "95290",
156 | "label": "colméia"
157 | },
158 | {
159 | "value": "92142",
160 | "label": "combinado"
161 | },
162 | {
163 | "value": "93130",
164 | "label": "conceição do tocantins"
165 | },
166 | {
167 | "value": "93211",
168 | "label": "couto magalhães"
169 | },
170 | {
171 | "value": "93238",
172 | "label": "cristalândia"
173 | },
174 | {
175 | "value": "73555",
176 | "label": "crixás do tocantins"
177 | },
178 | {
179 | "value": "73032",
180 | "label": "darcinópolis"
181 | },
182 | {
183 | "value": "93416",
184 | "label": "dianópolis"
185 | },
186 | {
187 | "value": "92185",
188 | "label": "divinópolis do tocantins"
189 | },
190 | {
191 | "value": "93459",
192 | "label": "dois irmãos do tocantins"
193 | },
194 | {
195 | "value": "93475",
196 | "label": "dueré"
197 | },
198 | {
199 | "value": "73296",
200 | "label": "esperantina"
201 | },
202 | {
203 | "value": "96830",
204 | "label": "fátima"
205 | },
206 | {
207 | "value": "96679",
208 | "label": "figueirópolis"
209 | },
210 | {
211 | "value": "93556",
212 | "label": "filadélfia"
213 | },
214 | {
215 | "value": "93653",
216 | "label": "formoso do araguaia"
217 | },
218 | {
219 | "value": "92240",
220 | "label": "goianorte"
221 | },
222 | {
223 | "value": "95338",
224 | "label": "goiatins"
225 | },
226 | {
227 | "value": "96270",
228 | "label": "guaraí"
229 | },
230 | {
231 | "value": "93858",
232 | "label": "gurupi"
233 | },
234 | {
235 | "value": "73598",
236 | "label": "ipueiras"
237 | },
238 | {
239 | "value": "94056",
240 | "label": "itacajá"
241 | },
242 | {
243 | "value": "94099",
244 | "label": "itaguatins"
245 | },
246 | {
247 | "value": "73202",
248 | "label": "itapiratins"
249 | },
250 | {
251 | "value": "94170",
252 | "label": "itaporã do tocantins"
253 | },
254 | {
255 | "value": "73369",
256 | "label": "jaú do tocantins"
257 | },
258 | {
259 | "value": "73253",
260 | "label": "juarina"
261 | },
262 | {
263 | "value": "73385",
264 | "label": "lagoa da confusão"
265 | },
266 | {
267 | "value": "73113",
268 | "label": "lagoa do tocantins"
269 | },
270 | {
271 | "value": "73407",
272 | "label": "lajeado"
273 | },
274 | {
275 | "value": "73601",
276 | "label": "lavandeira"
277 | },
278 | {
279 | "value": "95699",
280 | "label": "lizarda"
281 | },
282 | {
283 | "value": "73520",
284 | "label": "luzinópolis"
285 | },
286 | {
287 | "value": "92304",
288 | "label": "marianópolis do tocantins"
289 | },
290 | {
291 | "value": "73270",
292 | "label": "mateiros"
293 | },
294 | {
295 | "value": "73059",
296 | "label": "maurilândia do tocantins"
297 | },
298 | {
299 | "value": "94617",
300 | "label": "miracema do tocantins"
301 | },
302 | {
303 | "value": "94633",
304 | "label": "miranorte"
305 | },
306 | {
307 | "value": "94692",
308 | "label": "monte do carmo"
309 | },
310 | {
311 | "value": "73563",
312 | "label": "monte santo do tocantins"
313 | },
314 | {
315 | "value": "73342",
316 | "label": "muricilândia"
317 | },
318 | {
319 | "value": "94811",
320 | "label": "natividade"
321 | },
322 | {
323 | "value": "94838",
324 | "label": "nazaré"
325 | },
326 | {
327 | "value": "96636",
328 | "label": "nova olinda"
329 | },
330 | {
331 | "value": "92401",
332 | "label": "nova rosalândia"
333 | },
334 | {
335 | "value": "94994",
336 | "label": "novo acordo"
337 | },
338 | {
339 | "value": "73148",
340 | "label": "novo alegre"
341 | },
342 | {
343 | "value": "73172",
344 | "label": "novo jardim"
345 | },
346 | {
347 | "value": "73466",
348 | "label": "oliveira de fátima"
349 | },
350 | {
351 | "value": "73440",
352 | "label": "palmas"
353 | },
354 | {
355 | "value": "73083",
356 | "label": "palmeirante"
357 | },
358 | {
359 | "value": "73040",
360 | "label": "palmeiras do tocantins"
361 | },
362 | {
363 | "value": "96490",
364 | "label": "palmeirópolis"
365 | },
366 | {
367 | "value": "95192",
368 | "label": "paraíso do tocantins"
369 | },
370 | {
371 | "value": "95214",
372 | "label": "paranã"
373 | },
374 | {
375 | "value": "73261",
376 | "label": "pau d'arco"
377 | },
378 | {
379 | "value": "95257",
380 | "label": "pedro afonso"
381 | },
382 | {
383 | "value": "95273",
384 | "label": "peixe"
385 | },
386 | {
387 | "value": "92487",
388 | "label": "pequizeiro"
389 | },
390 | {
391 | "value": "95370",
392 | "label": "pindorama do tocantins"
393 | },
394 | {
395 | "value": "73016",
396 | "label": "piraquê"
397 | },
398 | {
399 | "value": "95478",
400 | "label": "pium"
401 | },
402 | {
403 | "value": "95516",
404 | "label": "ponte alta do bom jesus"
405 | },
406 | {
407 | "value": "95532",
408 | "label": "ponte alta do tocantins"
409 | },
410 | {
411 | "value": "92509",
412 | "label": "porto alegre do tocantins"
413 | },
414 | {
415 | "value": "95591",
416 | "label": "porto nacional"
417 | },
418 | {
419 | "value": "92525",
420 | "label": "praia norte"
421 | },
422 | {
423 | "value": "96296",
424 | "label": "presidente kennedy"
425 | },
426 | {
427 | "value": "73571",
428 | "label": "pugmil"
429 | },
430 | {
431 | "value": "73229",
432 | "label": "recursolândia"
433 | },
434 | {
435 | "value": "73024",
436 | "label": "riachinho"
437 | },
438 | {
439 | "value": "73431",
440 | "label": "rio da conceição"
441 | },
442 | {
443 | "value": "73415",
444 | "label": "rio dos bois"
445 | },
446 | {
447 | "value": "96792",
448 | "label": "rio sono"
449 | },
450 | {
451 | "value": "92541",
452 | "label": "sampaio"
453 | },
454 | {
455 | "value": "73156",
456 | "label": "sandolândia"
457 | },
458 | {
459 | "value": "73350",
460 | "label": "santa fé do araguaia"
461 | },
462 | {
463 | "value": "73130",
464 | "label": "santa maria do tocantins"
465 | },
466 | {
467 | "value": "73547",
468 | "label": "santa rita do tocantins"
469 | },
470 | {
471 | "value": "92584",
472 | "label": "santa rosa do tocantins"
473 | },
474 | {
475 | "value": "92606",
476 | "label": "santa tereza do tocantins"
477 | },
478 | {
479 | "value": "73539",
480 | "label": "santa terezinha do tocantins"
481 | },
482 | {
483 | "value": "73288",
484 | "label": "são bento do tocantins"
485 | },
486 | {
487 | "value": "73105",
488 | "label": "são félix do tocantins"
489 | },
490 | {
491 | "value": "73180",
492 | "label": "são miguel do tocantins"
493 | },
494 | {
495 | "value": "73393",
496 | "label": "são salvador do tocantins"
497 | },
498 | {
499 | "value": "96032",
500 | "label": "são sebastião do tocantins"
501 | },
502 | {
503 | "value": "92681",
504 | "label": "são valério"
505 | },
506 | {
507 | "value": "96598",
508 | "label": "silvanópolis"
509 | },
510 | {
511 | "value": "96130",
512 | "label": "sítio novo do tocantins"
513 | },
514 | {
515 | "value": "73377",
516 | "label": "sucupira"
517 | },
518 | {
519 | "value": "73199",
520 | "label": "tabocão"
521 | },
522 | {
523 | "value": "96156",
524 | "label": "taguatinga"
525 | },
526 | {
527 | "value": "73164",
528 | "label": "taipas do tocantins"
529 | },
530 | {
531 | "value": "73504",
532 | "label": "talismã"
533 | },
534 | {
535 | "value": "96199",
536 | "label": "tocantínia"
537 | },
538 | {
539 | "value": "96210",
540 | "label": "tocantinópolis"
541 | },
542 | {
543 | "value": "73458",
544 | "label": "tupirama"
545 | },
546 | {
547 | "value": "73237",
548 | "label": "tupiratins"
549 | },
550 | {
551 | "value": "96652",
552 | "label": "wanderlândia"
553 | },
554 | {
555 | "value": "96431",
556 | "label": "xambioá"
557 | }
558 | ]
--------------------------------------------------------------------------------