Skip to content

Commit 6576ace

Browse files
refactor: ( JobsFiltersCard )
- JobsFiltersCard: - Move ações do cabeçalho e exibição de metadados para este card. - Busca em linha com ações. - Seleção de palavra-chave e arquivo reorganizada. - JobsHeaderCard: - Simplificado para exibir apenas logotipo e alternância de tema. - Remove importação não utilizada do ThemeToggle. - JobsTableCard: - Adiciona margem inferior e espaçamento para banner de erro. - Reordena colunas da tabela: palavra-chave e fonte para o final. - Ajusta cor do link no modo escuro. - CSS/Tailwind: - Ajusta a cor do anel (--ring) para foco.
1 parent 960bf44 commit 6576ace

5 files changed

Lines changed: 80 additions & 92 deletions

File tree

frontend/src/App.tsx

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { JobsFiltersCard } from "@/components/JobsFiltersCard";
22
import { JobsHeaderCard } from "@/components/JobsHeaderCard";
33
import { JobsTableCard } from "@/components/JobsTableCard";
44
import { Button } from "@/components/ui/button";
5-
import { ThemeToggle } from "@/components/ui/theme-toggle";
65
import { useJobsData } from "@/hooks/useJobsData";
76
import { useJobsFiltering } from "@/hooks/useJobsFiltering";
87
import { useJobsPagination } from "@/hooks/useJobsPagination";
@@ -72,18 +71,7 @@ function App() {
7271
<div className="pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(circle_at_20%_15%,rgba(236,195,117,0.35),transparent_30%),radial-gradient(circle_at_80%_10%,rgba(92,151,191,0.28),transparent_35%),radial-gradient(circle_at_50%_95%,rgba(201,120,99,0.22),transparent_40%)] dark:bg-[radial-gradient(circle_at_20%_15%,rgba(240,180,95,0.18),transparent_30%),radial-gradient(circle_at_80%_10%,rgba(92,151,191,0.18),transparent_35%),radial-gradient(circle_at_50%_95%,rgba(201,120,99,0.15),transparent_40%)]" />
7372

7473
<section className="mx-auto flex w-full flex-col gap-6">
75-
<JobsHeaderCard
76-
meta={meta}
77-
actions={
78-
<>
79-
<Button onClick={handleScraper} disabled={loading || scraping}>
80-
<RefreshCcw className={`h-4 w-4 ${scraping ? "animate-spin" : ""}`} />
81-
{scraping ? "Buscando vagas..." : "Buscar vagas"}
82-
</Button>
83-
{/* <ThemeToggle theme={resolvedTheme} onToggle={toggleTheme} /> */}
84-
</>
85-
}
86-
/>
74+
<JobsHeaderCard />
8775

8876
<JobsFiltersCard
8977
search={search}
@@ -96,6 +84,17 @@ function App() {
9684
files={files}
9785
loading={loading || scraping}
9886
onRefresh={() => loadJobs(selectedFile)}
87+
meta={meta}
88+
actions={
89+
<>
90+
<Button onClick={handleScraper} disabled={loading || scraping}>
91+
<RefreshCcw
92+
className={`h-4 w-4 ${scraping ? "animate-spin" : ""}`}
93+
/>
94+
{scraping ? "Buscando vagas..." : "Buscar vagas"}
95+
</Button>
96+
</>
97+
}
9998
/>
10099

101100
<JobsTableCard
Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { Button } from "@/components/ui/button";
2-
import {
3-
CardContent,
4-
Card
5-
} from "@/components/ui/card";
1+
import { Card, CardContent } from "@/components/ui/card";
62
import { Input } from "@/components/ui/input";
73
import type { JobFile } from "@/types/jobs";
8-
import { RefreshCcw, Search } from "lucide-react";
4+
import { Search } from "lucide-react";
95
import type { Dispatch, SetStateAction } from "react";
6+
import type { JobsMeta } from "@/types/jobs";
7+
import type { ReactNode } from "react";
8+
import { Badge } from "@/components/ui/badge";
109

10+
import { BriefcaseBusiness, FileSpreadsheet } from "lucide-react";
1111
interface JobsFiltersCardProps {
1212
search: string;
1313
setSearch: Dispatch<SetStateAction<string>>;
@@ -19,6 +19,8 @@ interface JobsFiltersCardProps {
1919
files: JobFile[];
2020
loading: boolean;
2121
onRefresh: () => void;
22+
meta: JobsMeta;
23+
actions?: ReactNode;
2224
}
2325

2426
export function JobsFiltersCard({
@@ -32,58 +34,67 @@ export function JobsFiltersCard({
3234
files,
3335
loading,
3436
onRefresh,
37+
meta,
38+
actions,
3539
}: JobsFiltersCardProps) {
3640
return (
3741
<Card className="border-border/70 bg-card/85 backdrop-blur dark:bg-card/95">
38-
<CardContent className="grid gap-3 pt-6 md:grid-cols-4">
39-
<div className="relative md:col-span-2">
40-
<Search className="pointer-events-none absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
41-
<Input
42-
value={search}
43-
onChange={(event) => setSearch(event.target.value)}
44-
className="pl-9"
45-
placeholder="Buscar por titulo, empresa, local ou link"
46-
/>
42+
<CardContent className="flex flex-col gap-3 pt-6">
43+
{/* Campo de busca */}
44+
<div className="flex items-center gap-3">
45+
<div className="relative flex-1">
46+
<Search className="pointer-events-none absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
47+
<Input
48+
value={search}
49+
onChange={(event) => setSearch(event.target.value)}
50+
className="pl-9 w-full"
51+
placeholder="Buscar por titulo, empresa, local ou link"
52+
/>
53+
</div>
54+
<div className="flex items-center gap-2">{actions}</div>
4755
</div>
4856

49-
<select
50-
className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring"
51-
value={keywordFilter}
52-
onChange={(event) => setKeywordFilter(event.target.value)}
53-
>
54-
<option value="all">Todas as palavras-chave</option>
55-
{keywords.map((keyword) => (
56-
<option key={keyword} value={keyword}>
57-
{keyword}
58-
</option>
59-
))}
60-
</select>
61-
62-
<div className="flex gap-2">
57+
{/* Seção de filtros */}
58+
<div className="flex items-center gap-2 flex">
6359
<select
64-
className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring"
65-
value={selectedFile}
66-
onChange={(event) => setSelectedFile(event.target.value)}
60+
className="h-10 rounded-md border border-input bg-background px-3 text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring"
61+
value={keywordFilter}
62+
onChange={(event) => setKeywordFilter(event.target.value)}
6763
>
68-
{files.map((file) => (
69-
<option key={file.file} value={file.file}>
70-
{file.file}
64+
<option value="all">Todas as palavras-chave</option>
65+
{keywords.map((keyword) => (
66+
<option key={keyword} value={keyword}>
67+
{keyword}
7168
</option>
7269
))}
7370
</select>
74-
<Button
75-
variant="outline"
76-
size="sm"
77-
onClick={onRefresh}
78-
disabled={loading}
79-
>
80-
<RefreshCcw
81-
className={`h-4 w-4 ${loading ? "animate-spin" : ""}`}
82-
/>
83-
</Button>
71+
72+
<div>
73+
<select
74+
className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:border-ring"
75+
value={selectedFile}
76+
onChange={(event) => setSelectedFile(event.target.value)}
77+
>
78+
{files.map((file) => (
79+
<option key={file.file} value={file.file}>
80+
{file.file}
81+
</option>
82+
))}
83+
</select>
84+
</div>
85+
86+
<div className="flex items-center gap-2">
87+
<Badge variant="secondary" className="gap-1 text-xs">
88+
<FileSpreadsheet className="h-3.5 w-3.5" />
89+
{meta.file || "Sem arquivo"}
90+
</Badge>
91+
<Badge className="gap-1 text-xs">
92+
<BriefcaseBusiness className="h-3.5 w-3.5" />
93+
{meta.total} vagas
94+
</Badge>
95+
</div>
8496
</div>
8597
</CardContent>
86-
<Card className="border-border/70 bg-card/85 backdrop-blur dark:bg-card/95"></Card>
8798
</Card>
8899
);
89100
}
Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
import { Badge } from "@/components/ui/badge";
21
import {
3-
Card,
42
CardDescription,
5-
CardHeader,
63
CardTitle,
74
} from "@/components/ui/card";
85
import type { JobsMeta } from "@/types/jobs";
9-
import { BriefcaseBusiness, FileSpreadsheet } from "lucide-react";
106
import type { ReactNode } from "react";
117
import Logo from "../assets/logo-painel-vagas.svg";
128
import { ThemeToggle } from "@/components/ui/theme-toggle";
@@ -17,7 +13,7 @@ interface JobsHeaderCardProps {
1713
actions?: ReactNode;
1814
}
1915

20-
export function JobsHeaderCard({ meta, actions }: JobsHeaderCardProps) {
16+
export function JobsHeaderCard() {
2117
const { resolvedTheme, toggleTheme } = useTheme();
2218
return (
2319
<>
@@ -32,21 +28,7 @@ export function JobsHeaderCard({ meta, actions }: JobsHeaderCardProps) {
3228
<ThemeToggle theme={resolvedTheme} onToggle={toggleTheme} />
3329
</div>
3430
</div>
35-
<Card className="border-border/70 bg-card/85 backdrop-blur dark:bg-card/95">
36-
<CardHeader className="gap-4 pb-4 md:flex-row md:items-center md:justify-between">
37-
<div className="flex flex-wrap items-center gap-2">
38-
{actions}
39-
<Badge variant="secondary" className="gap-1 text-xs">
40-
<FileSpreadsheet className="h-3.5 w-3.5" />
41-
{meta.file || "Sem arquivo"}
42-
</Badge>
43-
<Badge className="gap-1 text-xs">
44-
<BriefcaseBusiness className="h-3.5 w-3.5" />
45-
{meta.total} vagas
46-
</Badge>
47-
</div>
48-
</CardHeader>
49-
</Card>
31+
5032
</>
5133
);
5234
}

frontend/src/components/JobsTableCard.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function JobsTableCard({
3535
onPageSizeChange,
3636
}: JobsTableCardProps) {
3737
return (
38-
<Card className="border-border/70 bg-card/90 backdrop-blur dark:bg-card/95">
38+
<Card className="border-border/70 bg-card/90 backdrop-blur dark:bg-card/95 mb-4">
3939
<CardHeader>
4040
<CardTitle className="text-lg">Vagas Encontradas</CardTitle>
4141
<CardDescription>
@@ -44,7 +44,7 @@ export function JobsTableCard({
4444
</CardHeader>
4545
<CardContent>
4646
{error ? (
47-
<div className="rounded-md border border-red-500/40 bg-red-500/10 p-4 text-sm text-red-700 dark:text-red-300">
47+
<div className="rounded-md border border-red-500/40 bg-red-500/10 p-4 text-sm text-red-700 dark:text-red-300 mb-4">
4848
{error}
4949
</div>
5050
) : null}
@@ -91,36 +91,36 @@ export function JobsTableCard({
9191
<Table>
9292
<TableHeader>
9393
<TableRow>
94-
<TableHead>Palavra-chave</TableHead>
9594
<TableHead>Titulo</TableHead>
9695
<TableHead>Empresa</TableHead>
97-
<TableHead>Fonte</TableHead>
9896
<TableHead>Local</TableHead>
9997
<TableHead>Link</TableHead>
98+
<TableHead>Palavra-chave</TableHead>
99+
<TableHead>Fonte</TableHead>
100100
</TableRow>
101101
</TableHeader>
102102
<TableBody>
103103
{paginatedJobs.map((job, index) => (
104104
<TableRow key={`${job.link || `${job.titulo || "vaga"}-${index}`}-${index}`}>
105-
<TableCell>{job.palavra || "-"}</TableCell>
106105
<TableCell className="font-medium">{job.titulo || "-"}</TableCell>
107106
<TableCell>{job.empresa || "-"}</TableCell>
108-
<TableCell>{job.source || "-"}</TableCell>
109107
<TableCell>{job.local || "-"}</TableCell>
110108
<TableCell>
111109
{job.link ? (
112110
<a
113111
href={job.link}
114112
target="_blank"
115113
rel="noreferrer"
116-
className="text-primary underline-offset-4 hover:underline"
114+
className="text-primary underline-offset-4 hover:underline dark:text-[#14AE5C]"
117115
>
118116
Abrir vaga
119117
</a>
120118
) : (
121119
"-"
122120
)}
123121
</TableCell>
122+
<TableCell>{job.palavra || "-"}</TableCell>
123+
<TableCell>{job.source || "-"}</TableCell>
124124
</TableRow>
125125
))}
126126

frontend/src/index.css

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
@tailwind components;
55
@tailwind utilities;
66

7-
option:hover {
8-
background-color: hsl(var(--accent));
9-
color: white;
10-
}
117

128
@layer base {
139
:root {
@@ -36,7 +32,7 @@ option:hover {
3632
--card: 216 26% 14%;
3733
--card-foreground: 210 30% 95%;
3834
--primary: 140 70% 20%;
39-
--primary-foreground: 218 35% 12%;
35+
/* --primary-foreground: 218 35% 12%; */
4036
--secondary: 216 20% 23%;
4137
--secondary-foreground: 210 20% 94%;
4238
--muted: 216 20% 19%;
@@ -45,7 +41,7 @@ option:hover {
4541
--accent-foreground: 0 0% 100%;
4642
--border: 216 16% 30%;
4743
--input: 216 16% 30%;
48-
--ring: 198 78% 63%;
44+
--ring: 140 75% 38%;
4945
color-scheme: dark;
5046
}
5147

0 commit comments

Comments
 (0)