Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | 1x 1x 1x 95x 2x 95x | import { Stack } from "@mui/material";
import { CheckIcon } from "@phosphor-icons/react";
import { ACTION_DENY_MESSAGE } from "@constants/permissions";
import GiveButton from "@shared/Button/GiveButton";
import GiveTooltip from "@shared/Tooltip/GiveTooltip";
import { GiveMemberNameCell } from "@features/Settings/Team/components/GiveMemberNameCell";
import { styled } from "@theme/v2/Provider";
import { AssignableHostRow } from "./host.types";
export const ASSIGNED_LABEL = "Assigned";
export const ASSIGN_LABEL = "Assign";
type Props = {
row: AssignableHostRow;
/** True while this row's own assign/unassign call is in flight. */
isPending: boolean;
canAssign: boolean;
onToggle: (row: AssignableHostRow) => void;
};
/**
* One row of the Assign Host modal (frame 8181-61190): the host's identity and
* the single control that both assigns and unassigns them.
*
* There is no separate unassign action by design — the mockup gives the
* assigned row's "✓ Assigned" the unassign click, so the row's state is also
* its affordance.
*/
const AssignHostRow = ({ row, isPending, canAssign, onToggle }: Props) => {
return (
<Row direction="row" alignItems="center" gap="12px">
{/* The same identity block the Host tab's rows draw, at the modal's
smaller pairing — one component, so the two lists cannot drift. */}
<GiveMemberNameCell
size="sm"
imageURL={row.imageURL}
firstName={row.name}
email={row.email}
// A host with no name on file leads with their email here, so the name
// line is dropped rather than rendered blank: this row is not a table
// column that has to keep the email in a fixed position.
fallbackToEmail
/>
<GiveTooltip
disableHoverListener={canAssign}
title={ACTION_DENY_MESSAGE}
fluidWidth
>
<GiveButton
// Ghost + check for the assigned state, outline for the invitation to
// act — the two read as state and action rather than two buttons.
variant={row.isAssigned ? "ghost" : "outline"}
size="small"
label={row.isAssigned ? ASSIGNED_LABEL : ASSIGN_LABEL}
startIcon={row.isAssigned ? <CheckIcon size={16} /> : undefined}
disabled={!canAssign || isPending}
onClick={() => onToggle(row)}
sx={{ whiteSpace: "nowrap", flexShrink: 0 }}
data-testid={`assign-host-action-${row.id}`}
/>
</GiveTooltip>
</Row>
);
};
export default AssignHostRow;
/**
* The mockup's 54px row: 8px/12px insets around a 38px identity block, with the
* rows separated by a 4px gap rather than a rule.
*/
const Row = styled(Stack)(({ theme }) => ({
minHeight: "54px",
padding: "8px 12px",
borderRadius: "8px",
"&:hover": {
backgroundColor: theme.palette.surface?.secondary,
},
}));
|