Team roles: construction personas with attire notes; fix dark-theme dropdown

- Replace roles with the 10 Construction Industry personas (Owner, Admin,
  Sales Manager, Sales Rep, Project Manager, Site Supervisor, Canvasser,
  Team Lead, Subcontractor, Other), each with description, attire &
  appearance cues and a common-overlap note
- Render Attire & appearance + Common overlap sections on each role card
- Remap members/invites to new role ids; add canvasser, team-lead and
  subcontractor members so every persona shows
- Set color-scheme per theme and style <select> options so the role
  dropdown is legible in dark mode

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-06 16:39:14 +05:30
parent f1a7bdc8ce
commit 25420bef8e
3 changed files with 178 additions and 31 deletions
+20 -3
View File
@@ -266,6 +266,23 @@ export function TeamManagement() {
</div>
<p className="tm-rolecard-desc">{r.description}</p>
<div className="tm-attire">
<div className="tm-attire-h"><Icon name="user" size={13} /> Attire &amp; appearance</div>
<ul className="tm-attire-list">
{r.attire.map((a) => (
<li key={a}><span className="tm-attire-dot" />{a}</li>
))}
</ul>
</div>
<div className="tm-overlap">
<span className="tm-overlap-ic"><Icon name="info" size={14} /></span>
<div>
<b>Common overlap</b>
<p>{r.overlap}</p>
</div>
</div>
<div className="tm-permlist">
{permissionGroups.map((g) => (
<div className="tm-permgroup" key={g.id}>
@@ -422,14 +439,14 @@ function RowMenu({ onEdit, onRemove, disabled }: { onEdit: () => void; onRemove:
function InviteModal({ open, roles, onClose, onInvite }: { open: boolean; roles: Role[]; onClose: () => void; onInvite: (email: string, roleId: string) => void }) {
const [email, setEmail] = useState("");
const [roleId, setRoleId] = useState("rep");
const [roleId, setRoleId] = useState("sales-rep");
const valid = /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email.trim());
const role = roles.find((r) => r.id === roleId);
function submit() {
if (!valid) return;
onInvite(email.trim(), roleId);
setEmail(""); setRoleId("rep");
setEmail(""); setRoleId("sales-rep");
}
return (
@@ -472,7 +489,7 @@ function InviteModal({ open, roles, onClose, onInvite }: { open: boolean; roles:
function EditMemberModal({ member, roles, onClose, onSave }: { member: Member | null; roles: Role[]; onClose: () => void; onSave: (id: string, patch: Partial<Member>) => void }) {
const [title, setTitle] = useState("");
const [roleId, setRoleId] = useState("rep");
const [roleId, setRoleId] = useState("sales-rep");
// Sync local form when a different member is opened.
const key = member?.id ?? "";