projects-detail.tsx (the bug surface):
- Team-add dropdown switches from 7 mixed values (lead/associate/pa/of_counsel/local_counsel/expert/observer) to 4 responsibility-only values (lead/member/observer/external). Default 'member'. Closes m's bug — staffing a person no longer pretends to define their firm tier.
- Team table gains a Profession column (between Name and Responsibility), so the firm-tier badge is glanceable at staffing time.
- form.team-profession-hint surfaces the picked person's profession or warns when none is set ("kann keine 4-Augen-Genehmigungen erteilen").
projects-detail.ts:
- ProjectTeamMember type gains responsibility + user_profession. Legacy .role field kept readable for the deprecation window but UI no longer uses it.
- renderTeam renders 3-column tabular layout. Profession pill is read-only (.projekt-team-profession[--none]); responsibility is visible inline (inline-edit deferred to follow-up).
- canManagePartnerUnits switches from m.role==="lead" to m.responsibility==="lead".
- Team-add submit posts {responsibility} instead of {role}.
admin-team.tsx + client/admin-team.ts:
- New Profession column with inline-edit dropdown (6 values + "(extern)" NULL option). User type extends with profession?: string|null.
- Read-only cell uses .projekt-team-profession pill with "(extern)" placeholder for NULL.
onboarding.tsx + client/onboarding.ts:
- New required profession <select> with default 'associate'. Six values match the new enum. Hint copy explains the difference from job_title.
- POST /api/onboarding payload gains profession field.
i18n.ts: ~30 new keys DE+EN — projects.team.profession.* / .responsibility.* / projects.detail.team.col.profession / .responsibility / .form.responsibility / .form.profession.* / admin.team.col.profession.* / onboarding.profession.* / projects.team.profession.none + .hint variants.
CSS:
- .projekt-team-profession pill (firm-tier, read-only).
- .projekt-team-profession--none italic-dashed for NULL professions.
- .projekt-team-responsibility pill (per-project).
- .form-hint--warning for the team-add no-profession warning.
Build: bun build.ts clean (1723 i18n keys, all referenced). go build + go vet + go test (pure-Go) clean.
116 lines
5.3 KiB
TypeScript
116 lines
5.3 KiB
TypeScript
import { h } from "./jsx";
|
|
import { Header } from "./components/Header";
|
|
import { Footer } from "./components/Footer";
|
|
import { PWAHead } from "./components/PWAHead";
|
|
|
|
export function renderOnboarding(): string {
|
|
return "<!DOCTYPE html>" + (
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
<meta name="theme-color" content="#BFF355" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
<PWAHead />
|
|
<title data-i18n="onboarding.title">Willkommen — Paliad</title>
|
|
<link rel="stylesheet" href="/assets/global.css" />
|
|
</head>
|
|
<body>
|
|
<Header />
|
|
|
|
<main className="login-main">
|
|
<div className="login-card onboarding-card">
|
|
<h1 className="onboarding-heading" data-i18n="onboarding.heading">Willkommen bei Paliad</h1>
|
|
<p className="onboarding-lede" data-i18n="onboarding.lede">
|
|
Bitte vervollständigen Sie Ihr Profil, damit Ihnen Akten, Fristen und Termine angezeigt werden können.
|
|
</p>
|
|
|
|
<form className="login-form" id="onboarding-form" autocomplete="off">
|
|
<label htmlFor="onb-display-name" className="login-label" data-i18n="onboarding.display_name">Anzeigename</label>
|
|
<input
|
|
type="text"
|
|
id="onb-display-name"
|
|
name="display_name"
|
|
required
|
|
autofocus
|
|
autocomplete="name"
|
|
className="login-input"
|
|
data-i18n-placeholder="onboarding.display_name.placeholder"
|
|
placeholder="Vor- und Nachname"
|
|
/>
|
|
|
|
<label htmlFor="onb-office" className="login-label" data-i18n="onboarding.office">Büro</label>
|
|
<select id="onb-office" name="office" required className="login-input">
|
|
{/* Options populated from /api/offices at init. */}
|
|
</select>
|
|
|
|
<label htmlFor="onb-job-title" className="login-label" data-i18n="onboarding.job_title">Berufsbezeichnung</label>
|
|
<input
|
|
type="text"
|
|
id="onb-job-title"
|
|
name="job_title"
|
|
list="onb-job-title-suggestions"
|
|
required
|
|
autocomplete="off"
|
|
className="login-input"
|
|
data-i18n-placeholder="onboarding.job_title.placeholder"
|
|
placeholder="z.B. Associate, Partner, Patentanwalt"
|
|
/>
|
|
<datalist id="onb-job-title-suggestions">
|
|
<option value="Partner"></option>
|
|
<option value="Associate"></option>
|
|
<option value="PA"></option>
|
|
<option value="Of Counsel"></option>
|
|
<option value="Counsel"></option>
|
|
<option value="Counsel Knowledge Lawyer"></option>
|
|
<option value="Knowledge Lawyer"></option>
|
|
<option value="Referendar/in"></option>
|
|
<option value="Trainee"></option>
|
|
<option value="wiss. Mitarbeiter/in"></option>
|
|
<option value="Sekretariat"></option>
|
|
</datalist>
|
|
|
|
<label htmlFor="onb-profession" className="login-label" data-i18n="onboarding.profession">Profession</label>
|
|
<select
|
|
id="onb-profession"
|
|
name="profession"
|
|
required
|
|
className="login-input"
|
|
>
|
|
<option value="associate" selected data-i18n="projects.team.profession.associate">Associate</option>
|
|
<option value="partner" data-i18n="projects.team.profession.partner">Partner</option>
|
|
<option value="of_counsel" data-i18n="projects.team.profession.of_counsel">Of Counsel</option>
|
|
<option value="senior_pa" data-i18n="projects.team.profession.senior_pa">Senior PA</option>
|
|
<option value="pa" data-i18n="projects.team.profession.pa">PA</option>
|
|
<option value="paralegal" data-i18n="projects.team.profession.paralegal">Paralegal</option>
|
|
</select>
|
|
<p className="login-hint" data-i18n="onboarding.profession.hint">
|
|
Strukturiertes Tier — steuert die 4-Augen-Genehmigung. Distinkt von der Berufsbezeichnung.
|
|
</p>
|
|
|
|
<label htmlFor="onb-partner-unit" className="login-label" data-i18n="onboarding.partner_unit">
|
|
Partner Unit <span className="login-label-optional" data-i18n="onboarding.optional">(optional)</span>
|
|
</label>
|
|
<select
|
|
id="onb-partner-unit"
|
|
name="partner_unit_id"
|
|
className="login-input"
|
|
>
|
|
{/* Options populated from /api/partner-units at init. */}
|
|
<option value="" data-i18n="onboarding.partner_unit.unassigned">(noch keine Zuordnung)</option>
|
|
</select>
|
|
|
|
<button type="submit" className="login-button" data-i18n="onboarding.submit">Profil anlegen</button>
|
|
</form>
|
|
</div>
|
|
</main>
|
|
|
|
<Footer />
|
|
|
|
<script src="/assets/onboarding.js"></script>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|