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 | 6x 6x 7x 65x 65x 6x 65x 65x | /**
* OrganizerChip — the canonical "assigned organizer" display used across the app
* (speaker kanban, Cockpit attention cards, task cards/lists).
*
* Renders an outlined chip with an initials avatar + the organizer's "First Last"
* display name, resolved from the organizer directory where `id === username`
* (see OrganizerSelect). Falls back to the raw username when the directory has no
* match, and renders nothing when no username is given.
*
* Self-resolving by default (calls `useOrganizers`); pass an `organizers` array to
* reuse a directory the parent already fetched.
*/
import React from 'react';
import { Avatar, Chip } from '@mui/material';
import type { ChipProps } from '@mui/material';
import { useOrganizers, type Organizer } from '@/components/shared/OrganizerSelect';
export interface OrganizerChipProps {
/** Organizer username (id === username in the directory). */
username?: string | null;
/** Optional pre-fetched directory to avoid a duplicate fetch. */
organizers?: Organizer[];
size?: ChipProps['size'];
sx?: ChipProps['sx'];
'data-testid'?: string;
}
/** First-letter-of-up-to-two name parts; handles "First Last" and "first.last". */
function initials(text: string): string {
const parts = text.split(/[.\s_-]+/).filter(Boolean);
return (parts[0]?.[0] ?? '').concat(parts[1]?.[0] ?? '').toUpperCase() || '?';
}
export const OrganizerChip: React.FC<OrganizerChipProps> = ({
username,
organizers,
size = 'small',
sx,
'data-testid': testId,
}) => {
const { organizers: fetched } = useOrganizers();
if (!username) return null;
const directory = organizers ?? fetched;
const name = directory.find((o) => o.id === username)?.name ?? username;
return (
<Chip
size={size}
variant="outlined"
label={name}
avatar={<Avatar sx={{ width: 18, height: 18, fontSize: '0.6rem' }}>{initials(name)}</Avatar>}
data-testid={testId}
sx={{ height: 22, '& .MuiChip-label': { fontSize: '0.7rem', px: 0.75 }, ...sx }}
/>
);
};
export default OrganizerChip;
|