Phase 5: Positions und Bereiche page with create/staff position modals

This commit is contained in:
2026-07-13 22:43:09 +02:00
parent f91a69147e
commit 80cfaa1e04
9 changed files with 527 additions and 7 deletions

View File

@@ -109,3 +109,23 @@ export async function changeEmployeeData(payload: {
export async function rehireEmployee(payload: { employee_id: string; rehire_date: string }): Promise<ActionResult> {
return callRpc("rehire_employee", payload, [`/employees/${payload.employee_id}`, "/employees", "/"]);
}
export type EmployeeSearchResult = { id: string; first_name: string; last_name: string; job_title: string; team_id: string | null };
// Shared by "Intern besetzen" (staff an open position) and the reorg
// workbench's "Mitarbeiter:in(nen)" multi-select — both search active/
// on-leave employees by name or title.
export async function searchActiveEmployees(query: string): Promise<EmployeeSearchResult[]> {
const supabase = await createClient();
let q = supabase
.from("employees_directory")
.select("id, first_name, last_name, job_title, team_id")
.in("status", ["Aktiv", "Karenz"])
.limit(20);
if (query.trim()) {
const term = query.trim();
q = q.or(`first_name.ilike.%${term}%,last_name.ilike.%${term}%,job_title.ilike.%${term}%`);
}
const { data } = await q;
return data ?? [];
}

View File

@@ -34,3 +34,24 @@ export async function staffPositionInternally(payload: {
revalidatePath("/");
return { success: true };
}
export type SuperiorSearchResult = { id: string; first_name: string; last_name: string; job_title: string; division_id: string };
// For "Position ausschreiben": superior lookup, filtered to team-leads when
// the new position is an IC role, or to division-heads/CEO when the new
// position is itself a team lead (§2).
export async function searchSuperiors(query: string, forLeadPosition: boolean): Promise<SuperiorSearchResult[]> {
const supabase = await createClient();
let q = supabase
.from("employees_directory")
.select("id, first_name, last_name, job_title, division_id")
.eq("status", "Aktiv")
.limit(20);
q = forLeadPosition ? q.lte("org_level", 1) : q.eq("is_lead", true).eq("org_level", 2);
if (query.trim()) {
const term = query.trim();
q = q.or(`first_name.ilike.%${term}%,last_name.ilike.%${term}%,job_title.ilike.%${term}%`);
}
const { data } = await q;
return data ?? [];
}