Phase 1: project foundation for Alpenwerk HR
Scaffolds the Next.js 16 / TypeScript strict / Tailwind v3 app per NEXTJS_REBUILD_SUPERPROMPT.md, and implements the Foundation slice from the Phase 1 plan: - Corrected Supabase schema (supabase/schema.sql): org units, employees, history, positions, hire drafts, saved reports, audit log, reorg scenarios, role-based profiles, salary-masking view, RLS policies, auto-derivation triggers, position-number generator. - Seed script (supabase/seed.ts): ~800 realistic Austrian employees across 9 divisions / 16 departments / 35 teams, history, 8 open positions, and hr_admin/manager test accounts. - Supabase clients (lib/supabase/*), design tokens (tailwind.config.ts), format/color helpers (lib/format.ts, lib/colors.ts). - Shared UI kit (components/ui): Avatar, StatusChip, Toast, Modal, SlideOver, SegmentedControl, Lookup. - Auth (login page, Server Actions) and proxy.ts (Next 16's replacement for middleware) guarding the authenticated route group. - Shell (Sidebar, Topbar, NewHireButton stub) and the Dashboard page, reading live data via employees_directory. Employees list/detail, hire wizard, action panels, org chart, positions, reports, and audit log are deferred to later phases per the plan.
This commit is contained in:
63
lib/colors.ts
Normal file
63
lib/colors.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import type { EmploymentStatus } from "./supabase/types";
|
||||
|
||||
const AVATAR_PALETTE = [
|
||||
"#d6046e",
|
||||
"#00666d",
|
||||
"#5c2e91",
|
||||
"#835b00",
|
||||
"#0e700e",
|
||||
"#b0035a",
|
||||
"#2b6cb0",
|
||||
"#a30354",
|
||||
];
|
||||
|
||||
// Stable per-employee avatar color when employees.avatar_color isn't set.
|
||||
export function avatarColorFor(seed: string): string {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < seed.length; i++) {
|
||||
hash = (hash << 5) - hash + seed.charCodeAt(i);
|
||||
hash |= 0;
|
||||
}
|
||||
return AVATAR_PALETTE[Math.abs(hash) % AVATAR_PALETTE.length];
|
||||
}
|
||||
|
||||
export const STATUS_STYLES: Record<EmploymentStatus, string> = {
|
||||
Aktiv: "bg-success-bg text-success-text",
|
||||
Karenz: "bg-warning-bg text-warning-text",
|
||||
Geplant: "bg-brand-100 text-brand-700",
|
||||
Ausgetreten: "bg-danger-bg text-danger-text",
|
||||
};
|
||||
|
||||
type ColorCategory = "success" | "danger" | "warning" | "info" | "purple" | "brand";
|
||||
|
||||
const CATEGORY_STYLES: Record<ColorCategory, string> = {
|
||||
success: "bg-success-bg text-success-text",
|
||||
danger: "bg-danger-bg text-danger-text",
|
||||
warning: "bg-warning-bg text-warning-text",
|
||||
info: "bg-info-bg text-info-text",
|
||||
purple: "bg-purple-bg text-purple-text",
|
||||
brand: "bg-brand-100 text-brand-700",
|
||||
};
|
||||
|
||||
// Audit-log / activity-feed action -> badge color, per the action list in
|
||||
// supabase/schema.sql's audit_log comment.
|
||||
const ACTION_CATEGORY: Record<string, ColorCategory> = {
|
||||
Neueinstellung: "success",
|
||||
Wiedereinstellung: "success",
|
||||
Rückkehr: "success",
|
||||
Austritt: "danger",
|
||||
Versetzung: "info",
|
||||
Ausschreibung: "info",
|
||||
"Interne Besetzung": "info",
|
||||
Beförderung: "purple",
|
||||
Reorganisation: "purple",
|
||||
"Reorganisation rückgängig": "purple",
|
||||
Karenz: "warning",
|
||||
Vertragsänderung: "warning",
|
||||
Stammdatenänderung: "warning",
|
||||
Gehaltsanpassung: "warning",
|
||||
};
|
||||
|
||||
export function actionBadgeStyle(action: string): string {
|
||||
return CATEGORY_STYLES[ACTION_CATEGORY[action] ?? "brand"];
|
||||
}
|
||||
Reference in New Issue
Block a user