Ability for admins to edit user titles
This commit is contained in:
+66
-18
@@ -919,6 +919,26 @@ function WorkspaceTab({ user, isAdmin, dbUsers = [], onSwitchUser, onCreateUser,
|
|||||||
const [wsTz, setWsTz] = React.useState(workspace ? workspace.timezone : '');
|
const [wsTz, setWsTz] = React.useState(workspace ? workspace.timezone : '');
|
||||||
const [wsSaved, setWsSaved] = React.useState(false);
|
const [wsSaved, setWsSaved] = React.useState(false);
|
||||||
|
|
||||||
|
// User editing state
|
||||||
|
const [editingUserId, setEditingUserId] = React.useState(null);
|
||||||
|
const [editName, setEditName] = React.useState('');
|
||||||
|
const [editRole, setEditRole] = React.useState('');
|
||||||
|
|
||||||
|
const startEditing = (u) => {
|
||||||
|
setEditingUserId(u.id);
|
||||||
|
setEditName(u.name);
|
||||||
|
setEditRole(u.role);
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancelEditing = () => {
|
||||||
|
setEditingUserId(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveUserEdit = async (id) => {
|
||||||
|
await onUpdateUserRole(id, { name: editName, role: editRole });
|
||||||
|
setEditingUserId(null);
|
||||||
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (workspace) {
|
if (workspace) {
|
||||||
setWsName(workspace.name);
|
setWsName(workspace.name);
|
||||||
@@ -1003,25 +1023,53 @@ function WorkspaceTab({ user, isAdmin, dbUsers = [], onSwitchUser, onCreateUser,
|
|||||||
{dbUsers.map(u => (
|
{dbUsers.map(u => (
|
||||||
<li key={u.id} className="member-row">
|
<li key={u.id} className="member-row">
|
||||||
<Avatar user={u} size={32} />
|
<Avatar user={u} size={32} />
|
||||||
<div className="member-row__meta">
|
<div className="member-row__meta" style={{ flex: 1 }}>
|
||||||
<div className="member-row__name">{u.name}</div>
|
{editingUserId === u.id ? (
|
||||||
<div className="member-row__role mono">{u.role} · {u.email || (u.id + '@murchison-auto.co')}</div>
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem' }}>
|
||||||
|
<input className="field__input field__input--sm" value={editName} onChange={e => setEditName(e.target.value)} autoFocus />
|
||||||
|
<input className="field__input field__input--sm" value={editRole} onChange={e => setEditRole(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="member-row__name" style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
|
||||||
|
{u.name}
|
||||||
|
{isAdmin && (
|
||||||
|
<button className="btn btn--ghost btn--sm" style={{ padding: '2px', height: 'auto', minWidth: 0, opacity: 0.5 }} onClick={() => startEditing(u)}>
|
||||||
|
<svg viewBox="0 0 16 16" width="10" height="10" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M12.5 3.5l-8 8V14h2.5l8-8-2.5-2.5z" strokeLinecap="round" strokeLinejoin="round"/><path d="M10.5 5.5l2 2" strokeLinecap="round" strokeLinejoin="round"/></svg>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="member-row__role mono">{u.role} · {u.email || (u.id + '@murchison-auto.co')}</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
|
||||||
|
{editingUserId === u.id ? (
|
||||||
|
<div style={{ display: 'flex', gap: '0.25rem' }}>
|
||||||
|
<button className="btn btn--ghost btn--sm" onClick={cancelEditing}>Cancel</button>
|
||||||
|
<button className="btn btn--primary btn--sm" onClick={() => saveUserEdit(u.id)}>Save</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{isAdmin ? (
|
||||||
|
<div className="picker member-row__type">
|
||||||
|
<button className={"picker__item"+(u.account_type==='standard'?' is-on':'')}
|
||||||
|
onClick={() => onUpdateUserRole(u.id, { account_type: 'standard' })}>Standard</button>
|
||||||
|
<button className={"picker__item"+(u.account_type==='admin'?' is-on':'')}
|
||||||
|
onClick={() => onUpdateUserRole(u.id, { account_type: 'admin' })}>Admin</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<span className="chip">{u.account_type}</span>
|
||||||
|
)}
|
||||||
|
{isAdmin && u.id !== user.id && (
|
||||||
|
<button className="member-row__del" onClick={() => {
|
||||||
|
if (confirm('Remove ' + u.name + '? Their tasks will move to ROD.')) onDeleteUser(u.id);
|
||||||
|
}} title="Remove user">×</button>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{isAdmin ? (
|
|
||||||
<div className="picker member-row__type">
|
|
||||||
<button className={"picker__item"+(u.account_type==='standard'?' is-on':'')}
|
|
||||||
onClick={() => onUpdateUserRole(u.id, { account_type: 'standard' })}>Standard</button>
|
|
||||||
<button className={"picker__item"+(u.account_type==='admin'?' is-on':'')}
|
|
||||||
onClick={() => onUpdateUserRole(u.id, { account_type: 'admin' })}>Admin</button>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<span className="chip">{u.account_type}</span>
|
|
||||||
)}
|
|
||||||
{isAdmin && u.id !== user.id && (
|
|
||||||
<button className="member-row__del" onClick={() => {
|
|
||||||
if (confirm('Remove ' + u.name + '? Their tasks will move to ROD.')) onDeleteUser(u.id);
|
|
||||||
}} title="Remove user">×</button>
|
|
||||||
)}
|
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
Reference in New Issue
Block a user