Mostrar oportunidades publicadas antes do registo de candidatos

This commit is contained in:
2026-10-30 21:15:27 +02:00
parent bf84575d10
commit c22846b2b1
10 changed files with 528 additions and 8 deletions
+76 -3
View File
@@ -5,9 +5,21 @@ import { Button } from '@/components/ui/button';
export default function Entry({
company,
portal,
opportunities = { data: [], prev_page_url: null, next_page_url: null },
}: {
company: { id: number; name: string };
portal: { version: number; registration_open: boolean; notice: string };
opportunities?: {
data: {
id: number;
title: string;
kind: string;
closes_on: string;
description: string;
}[];
prev_page_url: string | null;
next_page_url: string | null;
};
}) {
const login = useForm({ email: '', password: '' });
const register = useForm({
@@ -61,10 +73,71 @@ export default function Entry({
</h1>
<p>
Prepare o seu perfil e candidate-se às oportunidades
publicadas. O envio de anexos ainda está em desenvolvimento.
Criar um perfil não constitui candidatura ou contratação.
publicadas. Os documentos exigidos são indicados em cada
formulário. Criar um perfil não constitui candidatura ou
contratação.
</p>
<section className="space-y-3">
<section
className="space-y-3"
aria-label="Oportunidades publicadas"
>
<h2 className="text-xl font-semibold">
Oportunidades publicadas
</h2>
{opportunities.data.length === 0 && (
<p>Não existem oportunidades nesta página.</p>
)}
{opportunities.data.map((item) => (
<article
key={item.id}
className="space-y-2 rounded-lg border p-4"
>
<h3 className="font-semibold">{item.title}</h3>
<p>
{item.kind === 'service'
? 'Prestação de serviços'
: 'Recrutamento'}{' '}
· Prazo: {item.closes_on}
</p>
<details>
<summary className="cursor-pointer underline">
Consultar descrição publicada
</summary>
<p className="whitespace-pre-wrap">
{item.description}
</p>
</details>
<a
className="inline-block underline"
href="#candidate-login"
>
Entrar para preparar a candidatura
</a>
</article>
))}
<nav
aria-label="Páginas de oportunidades"
className="flex gap-4"
>
{opportunities.prev_page_url && (
<Link
href={opportunities.prev_page_url}
preserveScroll
>
Anterior
</Link>
)}
{opportunities.next_page_url && (
<Link
href={opportunities.next_page_url}
preserveScroll
>
Seguinte
</Link>
)}
</nav>
</section>
<section className="space-y-3" id="candidate-login">
<h2 className="text-xl font-semibold">Entrar</h2>
<form
className="space-y-3"
+17
View File
@@ -17,6 +17,7 @@ export default function Profile({
emailDeliveryAvailable = false,
accessStatus,
opportunities = [],
opportunityPagination,
submissions = [],
}: {
companyId: number;
@@ -26,6 +27,7 @@ export default function Profile({
emailDeliveryAvailable?: boolean;
accessStatus?: string | null;
opportunities?: { id: number; title: string; closes_on: string }[];
opportunityPagination?: { prev: string | null; next: string | null };
submissions?: { id: number; reference: string; created_at: string }[];
}) {
const form = useForm({
@@ -52,6 +54,21 @@ export default function Profile({
</Link>
</p>
))}
<nav
aria-label="Páginas de oportunidades"
className="flex gap-4"
>
{opportunityPagination?.prev && (
<Link href={opportunityPagination.prev} preserveScroll>
Anterior
</Link>
)}
{opportunityPagination?.next && (
<Link href={opportunityPagination.next} preserveScroll>
Seguinte
</Link>
)}
</nav>
<h2 className="text-xl font-semibold">
As minhas candidaturas
</h2>