@material-ui/core#CardHeader TypeScript Examples
The following examples show how to use
@material-ui/core#CardHeader.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Scores.tsx From dashboard with Apache License 2.0 | 6 votes |
ScoresSidebar = ({ score, close }: SidebarProps) => {
return (
<ScoresCard elevation={5}>
<CardHeader
action={
<IconButton aria-label="close" onClick={close}>
<Close />
</IconButton>
}
title="Score"
/>
<ScoresCardContent>
<List>
<Scores score={score} />
</List>
</ScoresCardContent>
</ScoresCard>
)
}
Example #2
Source File: PreviewPullRequestComponent.tsx From backstage with Apache License 2.0 | 6 votes |
PreviewPullRequestComponent = (
props: PreviewPullRequestComponentProps,
) => {
const { title, description, classes } = props;
return (
<Card variant="outlined" className={classes?.card}>
<CardHeader title={title} subheader="Create a new Pull Request" />
<CardContent className={classes?.cardContent}>
<MarkdownContent content={description} />
</CardContent>
</Card>
);
}
Example #3
Source File: SearchCard.tsx From covid19testing-map with GNU General Public License v3.0 | 6 votes |
SearchCard = () => {
const classes = useStyles();
const details: any = [];
Object.keys(labelMap).forEach((key: string) => {
details.push({
type: 'boolean',
title: labelMap[key].card,
key,
icon: labelMap[key].icon,
});
});
return (
<div>
<CardHeader title="Search" />
<CardContent>
<Typography color="textPrimary" className={classes.cardMargin}>
Great! Enter the name of their practice or the address of their clinic
to get started.
</Typography>
<Typography color="textPrimary" className={classes.cardMargin}>
If you can’t find them in our database, it’s unlikely that they are
offering COVID-19 testing to their patients at this time.
</Typography>
<CardActions />
</CardContent>
</div>
);
}
Example #4
Source File: PlayerCard.tsx From planning-poker with MIT License | 6 votes |
PlayerCard: React.FC<PlayerCardProps> = ({ game, player }) => {
return (
<Card
variant='outlined'
className='PlayerCard'
style={{
backgroundColor: getCardColor(game, player.value),
}}
>
<CardHeader
className='PlayerCardTitle'
title={player.name}
titleTypographyProps={{ variant: 'subtitle2', noWrap: true }}
/>
<CardContent className='PlayerCardContent'>
<Typography variant='h2' className='PlayerCardContentMiddle'>
{getCardValue(player, game)}
</Typography>
</CardContent>
</Card>
);
}
Example #5
Source File: Request.tsx From dashboard with Apache License 2.0 | 6 votes |
DocumentRequestCard = ({
requestBody,
defaultRequestBody,
setRequestBody,
}: Props) => {
let numDocuments = 0
try {
const req = JSON.parse(requestBody)
numDocuments = req.data.length
} catch (e) {}
return (
<DocumentCard>
<CardHeader
title={`Documents (${numDocuments})`}
titleTypographyProps={{ variant: "subtitle1" }}
/>
<CardContent>
<DocumentRequest
defaultRequestBody={defaultRequestBody}
requestBody={requestBody}
setRequestBody={setRequestBody}
/>
</CardContent>
</DocumentCard>
)
}
Example #6
Source File: index.tsx From react-app-architecture with Apache License 2.0 | 6 votes |
AuthorView = ({ author, date }: { author: Author; date?: string }) => {
const classes = useStyles();
return (
<div className={classes.author}>
{author.profilePicUrl ? (
<CardHeader
avatar={<Avatar aria-label={author.name} src={author.profilePicUrl} />}
title={author.name}
subheader={date ? convertToReadableDate(date) : ''}
/>
) : (
<CardHeader
avatar={<FirstLetter text={author.name} />}
title={author.name}
subheader={date ? convertToReadableDate(date) : ''}
/>
)}
</div>
);
}
Example #7
Source File: LatestBlock.tsx From metamask-snap-polkadot with Apache License 2.0 | 6 votes |
LatestBlock = (props: {block: BlockInfo}) => {
return (
<Card>
<CardHeader title="Latest block"/>
<CardContent>
<Grid container alignItems="center">
<Grid item md={6} xs={12}>
<Typography variant="h6">Block number:</Typography>
<Typography variant="subtitle2">{props.block.number}</Typography>
<Divider light/>
<Box m={"0.5rem"}/>
<Typography variant="h6">Hash:</Typography>
<Typography variant="subtitle2">{props.block.hash}</Typography>
</Grid>
</Grid>
</CardContent>
</Card>
);
}
Example #8
Source File: App.tsx From react-tutorials with MIT License | 6 votes |
function App() {
return (
<div className="App">
<header className="App-header">
<Centered>
<Card>
<CardHeader title="Signup For Our Newsletter" />
<CardContent>
<SubscribeForm />
</CardContent>
</Card>
</Centered>
</header>
</div>
)
}
Example #9
Source File: OnCallList.tsx From backstage-plugin-opsgenie with MIT License | 6 votes |
OnCallForScheduleCard = ({ schedule }: { schedule: Schedule }) => {
const title = (
<div style={{ display: "flex" }}>
<Tooltip title={schedule.enabled ? 'Enabled' : 'Disabled'}>
<div>{schedule.enabled ? <StatusOK /> : <StatusAborted />}</div>
</Tooltip>
{schedule.ownerTeam.name}
</div>
);
return (
<Card>
<CardHeader title={title} titleTypographyProps={{ variant: 'h6' }} />
<CardContent>
<OnCallForScheduleList schedule={schedule} />
</CardContent>
</Card>
);
}
Example #10
Source File: Timeline.tsx From ra-enterprise-demo with MIT License | 6 votes |
MyTimeline = (): ReactElement => {
const translate = useTranslate();
const {
data: events,
loaded,
ids,
} = useGetList<EventRecord>(
'events',
{ perPage: 100, page: 1 },
{ field: 'date', order: 'DESC' },
{}
);
const records = ids.map(id => events[id]);
return (
<>
<CardHeader title={translate('pos.dashboard.timeline')} />
<Timeline loaded={loaded} records={records} />
</>
);
}
Example #11
Source File: FlowChartNodes.tsx From dashboard with Apache License 2.0 | 5 votes |
ChartNode = ({
data,
selected,
isDragging,
type,
}: ChartNodeProps) => {
const { palette } = useTheme()
const { item, onScoreClick, hasInput = true, hasOutput = true, name } = data
const parentId = "parent_id" in item ? item.parent_id : undefined
const score = "score" in item ? item.score : undefined
const { id: itemId, uri, mime_type, text } = item
const elevation = isDragging ? 20 : selected ? 10 : 2
let style = {}
if (type === "match")
style = {
backgroundColor: palette.filters[0].main,
}
else if (type === "chunk")
style = {
backgroundColor: palette.filters[3].main,
}
return (
<div>
{hasInput && <Handle type="source" position={Position.Left}></Handle>}
<Card elevation={elevation} color="red" style={style}>
<CardHeader
style={{ paddingBottom: ".5em" }}
action={
score && (
<Button size="large" onClick={() => onScoreClick(score as Score)}>
score: {score.value || "0.0"}
</Button>
)
}
/>
<Box maxWidth="30rem" padding="1em" paddingTop="0em">
{text && <NodeBigText>"{text}"</NodeBigText>}
{uri && mimeTypeFromDataURI(uri) && <NodeMediaPreview uri={uri} />}
<Grid container>
<Grid item xs={6}>
{mime_type && (
<Typography color="textSecondary" gutterBottom>
{mime_type}
</Typography>
)}
</Grid>
<Grid item xs={6}>
<Box textAlign="right"></Box>
</Grid>
</Grid>
<div style={{ backgroundColor: "#ffffff80" }}>
<PropertyList data={item} key="main table" />
</div>
{parentId && (
<Box marginTop="0.5rem">
<Typography color="textSecondary">
ParentId: {parentId}
</Typography>
</Box>
)}
</Box>
</Card>
{hasOutput && <Handle type="target" position={Position.Right}></Handle>}
</div>
)
}
Example #12
Source File: AddShortcut.tsx From backstage with Apache License 2.0 | 5 votes |
AddShortcut = ({ onClose, anchorEl, api }: Props) => {
const classes = useStyles();
const alertApi = useApi(alertApiRef);
const { pathname } = useLocation();
const [formValues, setFormValues] = useState<FormValues>();
const open = Boolean(anchorEl);
const handleSave: SubmitHandler<FormValues> = async ({ url, title }) => {
const shortcut: Omit<Shortcut, 'id'> = { url, title };
try {
await api.add(shortcut);
alertApi.post({
message: `Added shortcut '${title}' to your sidebar`,
severity: 'success',
});
} catch (error) {
alertApi.post({
message: `Could not add shortcut: ${error.message}`,
severity: 'error',
});
}
onClose();
};
const handlePaste = () => {
setFormValues({ url: pathname, title: document.title });
};
const handleClose = () => {
setFormValues(undefined);
onClose();
};
return (
<Popover
open={open}
anchorEl={anchorEl}
TransitionProps={{ onExit: handleClose }}
onClose={onClose}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
>
<Card className={classes.card}>
<CardHeader
className={classes.header}
title="Add Shortcut"
titleTypographyProps={{ variant: 'subtitle2' }}
action={
<Button
className={classes.button}
variant="text"
size="small"
color="primary"
onClick={handlePaste}
>
Use current page
</Button>
}
/>
<ShortcutForm
onClose={handleClose}
onSave={handleSave}
formValues={formValues}
/>
</Card>
</Popover>
);
}
Example #13
Source File: PricingPlan.tsx From clearflask with Apache License 2.0 | 5 votes |
render() {
return (
<Card elevation={0} className={classNames(this.props.className, this.props.classes.box, this.props.selected && this.props.classes.boxSelected)}>
<CardHeader
title={(
<div className={this.props.classes.title}>
{this.props.plan.title}
{this.props.plan.beta && (
<div className={this.props.classes.beta}>
EARLY<br />ACCESS
</div>
)}
</div>
)}
titleTypographyProps={{ align: 'center' }}
/>
<CardContent>
{this.renderPriceTag()}
{(this.props.overridePerks || this.props.plan.perks).map(perk => (
<div key={perk.desc} style={{ display: 'flex', alignItems: 'baseline' }}>
<CheckIcon fontSize='inherit' />
<Typography variant='subtitle1'>
{perk.desc}
{!!perk.terms && (<>
<HelpPopper description={perk.terms} />
</>)}
</Typography>
</div>
))}
</CardContent>
{
!!this.props.actionTitle && (
<CardActions className={this.props.classes.actions}>
{this.props.actionType === 'radio' ? (
<FormControlLabel
label={this.props.actionTitle}
control={(
<Radio
checked={this.props.selected}
color='primary'
onChange={e => this.props.actionOnClick && this.props.actionOnClick()}
disabled={!this.props.actionOnClick}
/>
)}
/>
) : (
<Button
color='primary'
variant='contained'
disableElevation
style={{ fontWeight: 900 }}
onClick={this.props.actionOnClick}
disabled={!this.props.actionOnClick}
{...(this.props.actionTo ? {
component: Link,
to: this.props.actionTo,
} : {})}
{...(this.props.actionToExt ? {
component: 'a',
href: this.props.actionToExt,
} : {})}
>
{this.props.actionTitle}
</Button>
)}
</CardActions>
)
}
{this.props.remark && (
<div className={this.props.classes.remark}>
<Typography variant='caption' component='div' color='textSecondary'>{this.props.remark}</Typography>
</div>
)}
</Card >
);
}
Example #14
Source File: StatsCard.component.tsx From akashlytics with GNU General Public License v3.0 | 5 votes |
export function StatsCard({
number,
text,
tooltip,
actionButton,
graphPath,
diffNumber,
diffPercent,
}: IStatsCardProps) {
const classes = useStyles();
const mediaQuery = useMediaQueryContext();
return (
<Card
className={clsx(classes.root, { [classes.rootSmall]: mediaQuery.smallScreen })}
elevation={3}
>
<CardHeader
classes={{ title: classes.number, root: classes.cardHeader, subheader: classes.subHeader }}
title={number}
subheader={diffNumber && (
<>
<DiffNumber value={diffNumber} />
<DiffPercentageChip value={diffPercent} />
</>
)}
/>
<div className={classes.cardContent}>
<p className={classes.title}>{text}</p>
</div>
<CardActions>
{tooltip && (
<CustomTooltip arrow enterTouchDelay={0} leaveTouchDelay={10000} title={tooltip}>
<HelpIcon className={classes.tooltip} />
</CustomTooltip>
)}
{graphPath && (
<Button
aria-label="graph"
component={RouterLink}
to={graphPath}
size="small"
classes={{ label: classes.actionButtonLabel }}
>
<Box component="span" marginRight=".5rem">
Graph
</Box>
<TimelineIcon className={classes.actionIcon} />
</Button>
)}
{actionButton}
</CardActions>
</Card>
);
}
Example #15
Source File: RecentGames.tsx From planning-poker with MIT License | 5 votes |
RecentGames = () => {
const history = useHistory();
const [recentGames, setRecentGames] = useState<Game[] | undefined>(undefined);
useEffect(() => {
async function fetchData() {
const games = await getPlayerRecentGames();
if (games) {
setRecentGames(games);
}
}
fetchData();
}, []);
const isEmptyRecentGames = (): boolean => {
if (!recentGames) {
return true;
}
if (recentGames && recentGames.length === 0) {
return true;
}
return false;
};
return (
<Card variant='outlined' className='RecentGamesCard'>
<CardHeader
className='RecentGamesCardTitle'
title='Recent Session'
titleTypographyProps={{ variant: 'h6', noWrap: true }}
/>
<CardContent className='RecentGamesCardContent'>
{isEmptyRecentGames() && (
<Typography variant='body2'>No recent sessions found</Typography>
)}
{recentGames && recentGames.length > 0 && (
<TableContainer className='RecentGamesTableContainer'>
<Table stickyHeader>
<TableHead>
<TableRow>
<TableCell>Name</TableCell>
<TableCell>Created By</TableCell>
<TableCell></TableCell>
</TableRow>
</TableHead>
<TableBody>
{recentGames.map((recentGame) => (
<TableRow
hover
key={recentGame.id}
className='RecentGamesTableRow'
onClick={() => history.push(`/game/${recentGame.id}`)}
>
<TableCell>{recentGame.name}</TableCell>
<TableCell align='left'>{recentGame.createdBy}</TableCell>
<TableCell align='left'></TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
)}
</CardContent>
</Card>
);
}
Example #16
Source File: Aside.tsx From ra-enterprise-demo with MIT License | 5 votes |
ReviewEvent: FC<{ record?: RaRecord; basePath?: string }> = ({
record,
basePath,
}) => {
const translate = useTranslate();
const classes = useEventStyles();
if (!record) {
return null;
}
return (
<Card className={classes.card}>
<CardHeader
className={classes.cardHeader}
avatar={
<Avatar
aria-label={translate('resources.reviews.name', {
smart_count: 1,
})}
>
<review.icon />
</Avatar>
}
action={<EditButton record={record} basePath="/reviews" />}
title={
<span>
{translate('resources.reviews.relative_to_poster')}{' '}
<ProductReferenceField
resource="reviews"
record={record}
basePath={basePath}
/>
</span>
}
subheader={
<>
<Typography variant="body2">{record.date}</Typography>
<StarRatingField record={record} />
<Typography variant="inherit" className={classes.clamp}>
{record.comment}
</Typography>
</>
}
/>
</Card>
);
}
Example #17
Source File: Request.tsx From dashboard with Apache License 2.0 | 5 votes |
Request = ({
requestBody,
defaultRequestBody,
setRequestBody,
}: Props) => {
const [tab, setTab] = useState(0)
return (
<Card>
<CardHeader
title="Request Body"
titleTypographyProps={{ variant: "subtitle1" }}
/>
<CardContent>
<Grid container direction={"row"}>
<Grid item xs={2}>
<Box p={2}>
<Tabs
orientation="vertical"
aria-label="request type"
value={tab}
onChange={(e, v) => setTab(v)}
>
<Tab label="Formatted" />
<Tab label="Raw" />
</Tabs>
</Box>
</Grid>
<Grid item xs={10}>
<TabPanel value={tab} index={0}>
<DocumentRequest
defaultRequestBody={defaultRequestBody}
requestBody={requestBody}
setRequestBody={setRequestBody}
/>
</TabPanel>
<TabPanel value={tab} index={1}>
<TextInput
id="filled-textarea"
label="Request body"
placeholder="Request body"
multiline
minRows={10}
maxRows={20}
variant="outlined"
value={requestBody}
onChange={(e) => setRequestBody(e.target.value)}
/>
</TabPanel>
</Grid>
</Grid>
</CardContent>
</Card>
)
}
Example #18
Source File: SearchResults.tsx From cognitive-search-static-web-apps-sample-ui with MIT License | 5 votes |
render(): JSX.Element {
const state = this.props.state;
var cards = state.searchResults.map(item => {
return (
<Grid key={item.key} item sm={12} md={6}>
<Card raised>
<CardHeader
avatar={
<Link onClick={() => state.showDetails(item)}>
<Avatar><FolderIcon /></Avatar>
</Link>
}
title={<Link variant="h6" onClick={() => state.showDetails(item)}>{item.name}</Link>}
/>
<CardContent>
{item.otherFields.map(val => { return (
<Typography variant="body2" key={val}>
{val}
</Typography>
)})}
</CardContent>
<TagButtonsDiv>
{item.keywords.map(kw => { return (
<TagChip
key={kw}
label={kw}
size="small"
onClick={() => state.facetsState.filterBy(item.keywordsFieldName, kw)}
disabled={this.props.inProgress}
/>
); })}
</TagButtonsDiv>
</Card>
</Grid>
);
});
return (<>
<div>
<CountersTypography variant="caption" >
{state.searchResults.length} of {state.totalResults} results shown
</CountersTypography>
{!!state.inProgress && (<TopLinearProgress />)}
</div>
<ResultsGrid container spacing={3}>
{!!state.errorMessage && (
<ErrorChip color="secondary" label={state.errorMessage} onDelete={() => state.HideError()}/>
)}
{cards}
</ResultsGrid>
{(!!state.inProgress && !!state.searchResults.length) && (<LinearProgress />)}
</>);
}
Example #19
Source File: Aside.tsx From ra-enterprise-demo with MIT License | 5 votes |
OrderEvent: FC<{ record?: RaRecord; basePath?: string }> = ({
record,
basePath,
}) => {
const translate = useTranslate();
const classes = useEventStyles();
if (!record) {
return null;
}
return (
<Card className={classes.card}>
<CardHeader
className={classes.cardHeader}
avatar={
<Avatar
aria-label={translate('resources.commands.name', {
smart_count: 1,
})}
>
<order.icon />
</Avatar>
}
action={<EditButton record={record} basePath="/commands" />}
title={`${translate('resources.commands.name', {
smart_count: 1,
})} #${record.reference}`}
subheader={
<>
<Typography variant="body2">{record.date}</Typography>
<Typography variant="body2" color="textSecondary">
{translate('resources.commands.nb_items', {
smart_count: record.basket.length,
_: '1 item |||| %{smart_count} items',
})}
-
<NumberField
source="total"
options={{
style: 'currency',
currency: 'USD',
}}
record={record}
basePath={basePath}
/>
-
<TextField
source="status"
record={record}
basePath={basePath}
/>
</Typography>
</>
}
/>
</Card>
);
}
Example #20
Source File: SQFormScrollableCardsMenuWrapper.tsx From SQForm with MIT License | 5 votes |
export default function SQFormScrollableCardsMenuWrapper({
title,
children,
}: SQFormScrollableCardsMenuWrapperProps): JSX.Element {
const classes = useStyles();
const menuItems = React.useMemo(
() =>
React.Children.map(children, (child) => {
return {
label: child.props.label,
value: child.props.value,
};
}),
[children]
);
const [selectedTab, setSelectedTab] = React.useState(() => menuItems[0]);
const handleChange = (selectedMenuItemValue: string) => {
const newSelection = menuItems.find(
(item) => item.value === selectedMenuItemValue
);
if (
typeof newSelection !== 'undefined' &&
selectedTab.value !== newSelection.value
) {
setSelectedTab(newSelection);
}
};
const SelectedForm = React.useMemo(() => {
const selected = getSelectedComponent(selectedTab, children);
return selected;
}, [selectedTab, children]);
return (
<Card raised={true} elevation={1} square={true} className={classes.card}>
<CardHeader
classes={{
action: classes.action,
title: classes.title,
}}
title={title}
className={classes.cardHeader}
titleTypographyProps={{variant: 'h5'}}
action={
<CardPopoverMenu
tabs={menuItems}
selectedTab={selectedTab}
selectTab={handleChange}
/>
}
/>
{SelectedForm}
</Card>
);
}
Example #21
Source File: index.tsx From aqualink-app with MIT License | 5 votes |
Bleaching = ({ dailyData, classes }: BleachingProps) => {
const relativeTime = toRelativeTime(dailyData.date);
return (
<Card className={classes.root}>
<CardHeader
className={classes.header}
title={
<Grid container>
<Grid item xs={12}>
<Typography
className={classes.cardTitle}
color="textSecondary"
variant="h6"
>
HEAT STRESS ALERT LEVEL
</Typography>
</Grid>
</Grid>
}
/>
<CardContent className={classes.contentWrapper}>
<Grid
className={classes.content}
container
alignItems="center"
alignContent="space-between"
justify="center"
item
xs={12}
>
<img
className={classes.alertImage}
src={findIntervalByLevel(dailyData.weeklyAlertLevel).image}
alt="alert-level"
/>
<UpdateInfo
relativeTime={relativeTime}
timeText="Last data received"
imageText="NOAA CRW"
live={false}
frequency="daily"
href="https://coralsitewatch.noaa.gov/product/5km/index_5km_baa_max_r07d.php"
withMargin
/>
</Grid>
</CardContent>
</Card>
);
}
Example #22
Source File: index.tsx From react-app-architecture with Apache License 2.0 | 5 votes |
BlogCard = ({
blog,
selection,
}: {
blog: Blog;
selection?: (blog: Blog) => void;
}): ReactElement => {
const classes = useStyles();
const { title, description, author, imgUrl, blogUrl, publishedAt } = blog;
return (
<Card
className={classes.card}
raised={true}
onClick={() => {
selection && selection(blog);
}}
>
<CardActionArea className={classes.cardContent} component={Link} to={'/blog/' + blogUrl}>
<CardMedia
className={classes.cardMedia}
component="img"
alt={title}
src={imgUrl}
title={title}
/>
<CardContent>
<Typography variant="h6" component="h2" className={classes.cardTitle}>
{title}
</Typography>
<Typography
variant="body2"
color="textSecondary"
component="p"
className={classes.cardDescription}
>
{description}
</Typography>
</CardContent>
<CardHeader
className={classes.cardAuthor}
avatar={
author.profilePicUrl ? (
<Avatar aria-label={author.name} src={author.profilePicUrl} />
) : (
<FirstLetter text={author.name} />
)
}
title={author.name}
subheader={convertToReadableDate(publishedAt)}
/>
</CardActionArea>
</Card>
);
}
Example #23
Source File: PullRequestCard.tsx From backstage with Apache License 2.0 | 5 votes |
PullRequestCard = ({
pullRequest,
simplified,
}: PullRequestCardProps) => {
const title = (
<Link to={pullRequest.link ?? ''} title={pullRequest.description}>
{pullRequest.title}
</Link>
);
const repoLink = (
<Link to={pullRequest.repository?.url ?? ''} color="inherit">
{pullRequest.repository?.name}
</Link>
);
const creationDate = pullRequest.creationDate
? DateTime.fromISO(pullRequest.creationDate).toRelative()
: undefined;
const subheader = (
<span>
{repoLink} · {creationDate}
</span>
);
const avatar = (
<Avatar
displayName={pullRequest.createdBy?.displayName}
picture={pullRequest.createdBy?.imageUrl}
customStyles={{ width: '2.5rem', height: '2.5rem', fontSize: '1rem' }}
/>
);
const classes = useStyles();
return (
<Card
classes={{ root: classes.card }}
data-pull-request-id={pullRequest.pullRequestId}
>
<CardHeader
avatar={avatar}
title={title}
subheader={subheader}
action={
<AutoCompleteIcon hasAutoComplete={pullRequest.hasAutoComplete} />
}
classes={{
...(simplified && { root: classes.cardHeaderSimplified }),
action: classes.cardHeaderAction,
}}
/>
{!simplified && (
<CardContent className={classes.content}>
{pullRequest.policies && (
<PullRequestCardPolicies
policies={pullRequest.policies}
className={classes.policies}
/>
)}
{pullRequest.reviewers && (
<PullRequestCardReviewers reviewers={pullRequest.reviewers} />
)}
</CardContent>
)}
</Card>
);
}
Example #24
Source File: index.tsx From react-app-architecture with Apache License 2.0 | 5 votes |
InfoCard = ({
imgUrl,
href,
title,
subtitle,
description,
action = 'Learn More',
}: {
imgUrl: string;
href: string;
title: string;
subtitle: string;
description: string;
action?: string;
}) => {
const classes = useStyles();
return (
<Card className={classes.infoCard} raised={true}>
<CardHeader
avatar={<Avatar className={classes.avatar} src={imgUrl} />}
title={title}
subheader={subtitle}
/>
<CardContent>
<Typography variant="subtitle1" component="p">
{description}
</Typography>
</CardContent>
<CardActions className={classes.cardAction}>
<Button
className={classes.button}
variant="contained"
component="a"
size="small"
color="primary"
href={href}
target="_blank"
>
{action}
</Button>
</CardActions>
</Card>
);
}
Example #25
Source File: FileList.tsx From aqualink-app with MIT License | 5 votes |
FileList = ({ files, onFileDelete }: FileListProps) => {
const classes = useStyles();
const errors = useSelector(uploadsErrorSelector) as Record<
string,
string | null
>;
const loading = useSelector(uploadsInProgressSelector);
const uploadResponse = useSelector(uploadsResponseSelector);
return (
<Grid container spacing={2} className={classes.root}>
<Grid item xs={12}>
<Typography gutterBottom variant="h6">
{files.length} {pluralize(files.length, "file")}{" "}
{loading ? "uploading" : "to be uploaded"}
</Typography>
</Grid>
{files.map(({ name }) => (
<Grid item key={name} lg={4} md={6} xs={12}>
<Card className={classes.card} variant="outlined">
<CardHeader
className={classNames({ [classes.loading]: loading })}
classes={{ content: classes.cardContent }}
title={
<Typography
className={classes.cardHeaderTitle}
title={name}
color="textSecondary"
variant="h6"
>
{name}
</Typography>
}
action={
<Tooltip title="Remove file" arrow placement="top">
<IconButton
disabled={loading}
onClick={() => onFileDelete(name)}
>
<CloseIcon />
</IconButton>
</Tooltip>
}
avatar={<FileIcon className={classes.fileIcon} />}
/>
{loading && (
<CircularProgress
size={CIRCULAR_PROGRESS_SIZE}
className={classes.circularProgress}
/>
)}
</Card>
{errors?.[name] && <Alert severity="error">{errors[name]}</Alert>}
{!loading &&
!!uploadResponse?.some((x) => x.file === name && !x.error) && (
<Alert severity="success">File uploaded</Alert>
)}
</Grid>
))}
</Grid>
);
}
Example #26
Source File: GameController.tsx From planning-poker with MIT License | 4 votes |
GameController: React.FC<GameControllerProps> = ({ game, currentPlayerId }) => {
const history = useHistory();
const [showCopiedMessage, setShowCopiedMessage] = useState(false);
const copyInviteLink = () => {
const dummy = document.createElement('input');
const url = `${window.location.origin}/join/${game.id}`;
document.body.appendChild(dummy);
dummy.value = url;
dummy.select();
document.execCommand('copy');
document.body.removeChild(dummy);
setShowCopiedMessage(true);
};
const leaveGame = () => {
history.push(`/`);
};
const isModerator = (moderatorId: string, currentPlayerId: string) => {
return moderatorId === currentPlayerId;
};
return (
<Grow in={true} timeout={2000}>
<div className='GameController'>
<Card variant='outlined' className='GameControllerCard'>
<CardHeader
title={game.name}
titleTypographyProps={{ variant: 'h6' }}
action={
<div className='GameControllerCardHeaderAverageContainer'>
<Typography variant='subtitle1'>{game.gameStatus}</Typography>
{game.gameType !== GameType.TShirt && (
<>
<Divider className='GameControllerDivider' orientation='vertical' flexItem />
<Typography variant='subtitle1'>Average:</Typography>
<Typography variant='subtitle1' className='GameControllerCardHeaderAverageValue'>
{game.average || 0}
</Typography>
</>
)}
</div>
}
className='GameControllerCardTitle'
></CardHeader>
<CardContent className='GameControllerCardContentArea'>
{isModerator(game.createdById, currentPlayerId) && (
<>
<div className='GameControllerButtonContainer'>
<div className='GameControllerButton'>
<IconButton onClick={() => finishGame(game.id)} data-testid='reveal-button' color='primary'>
<VisibilityIcon fontSize='large' style={{ color: green[500] }} />
</IconButton>
</div>
<Typography variant='caption'>Reveal</Typography>
</div>
<div className='GameControllerButtonContainer'>
<div className='GameControllerButton'>
<IconButton data-testid={'restart-button'} onClick={() => resetGame(game.id)}>
<RefreshIcon fontSize='large' color='error' />
</IconButton>
</div>
<Typography variant='caption'>Restart</Typography>
</div>
</>
)}
<div className='GameControllerButtonContainer'>
<div className='GameControllerButton'>
<IconButton data-testid='exit-button' onClick={() => leaveGame()}>
<ExitToApp fontSize='large' style={{ color: orange[500] }} />
</IconButton>
</div>
<Typography variant='caption'>Exit</Typography>
</div>
<div title='Copy invite link' className='GameControllerButtonContainer'>
<div className='GameControllerButton'>
<IconButton data-testid='invite-button' onClick={() => copyInviteLink()}>
<LinkIcon fontSize='large' style={{ color: blue[500] }} />
</IconButton>
</div>
<Typography variant='caption'>Invite</Typography>
</div>
</CardContent>
</Card>
<Snackbar
anchorOrigin={{ horizontal: 'right', vertical: 'top' }}
open={showCopiedMessage}
autoHideDuration={5000}
onClose={() => setShowCopiedMessage(false)}
>
<Alert severity='success'>Invite Link copied to clipboard!</Alert>
</Snackbar>
</div>
</Grow>
);
}
Example #27
Source File: index.tsx From aqualink-app with MIT License | 4 votes |
Sensor = ({ depth, id, data, classes }: SensorProps) => {
const { topTemperature, bottomTemperature } = data;
const relativeTime =
(topTemperature?.timestamp && toRelativeTime(topTemperature.timestamp)) ||
(bottomTemperature?.timestamp &&
toRelativeTime(bottomTemperature.timestamp));
const hasSpotter = Boolean(topTemperature?.value || bottomTemperature?.value);
const user = useSelector(userInfoSelector);
const metrics = [
{
label: "TEMP AT 1m",
value: `${formatNumber(topTemperature?.value, 1)}°C`,
},
{
label: `TEMP AT ${depth ? `${depth}m` : "DEPTH"}`,
value: `${formatNumber(bottomTemperature?.value, 1)}°C`,
},
];
const [alertText, clickable] = getApplicationTag(user, id);
return (
<Card className={classes.root}>
<CardHeader
className={classes.header}
title={
<Grid container>
<Grid item>
<Typography className={classes.cardTitle} variant="h6">
BUOY OBSERVATION
</Typography>
</Grid>
</Grid>
}
/>
<CardContent className={classes.content}>
<Box
p="1rem"
display="flex"
flexGrow={1}
style={{ position: "relative" }}
>
<Grid container spacing={1}>
{metrics.map(({ label, value }) => (
<Grid key={label} item xs={12}>
<Typography
className={classes.contentTextTitles}
variant="subtitle2"
>
{label}
</Typography>
<Typography className={classes.contentTextValues} variant="h3">
{value}
</Typography>
</Grid>
))}
</Grid>
<Box position="absolute" bottom={-15} right={0}>
<img alt="sensor" src={sensor} />
</Box>
</Box>
{hasSpotter ? (
<UpdateInfo
relativeTime={relativeTime}
timeText="Last data received"
live
frequency="hourly"
withMargin
/>
) : (
<Grid
className={classes.noSensorAlert}
container
alignItems="center"
justify="center"
>
{clickable ? (
<Link
className={classes.newSpotterLink}
to={`/sites/${id}/apply`}
>
<Typography variant="h6">{alertText}</Typography>
</Link>
) : (
<Typography variant="h6">{alertText}</Typography>
)}
</Grid>
)}
</CardContent>
</Card>
);
}
Example #28
Source File: JoinGame.tsx From planning-poker with MIT License | 4 votes |
JoinGame = () => {
const history = useHistory();
let { id } = useParams<{ id: string }>();
const [joinGameId, setJoinGameId] = useState(id);
const [playerName, setPlayerName] = useState('');
const [gameFound, setIsGameFound] = useState(true);
useEffect(() => {
async function fetchData() {
if (joinGameId) {
if (await getGame(joinGameId)) {
setIsGameFound(true);
if (isCurrentPlayerInGame(joinGameId)) {
history.push(`/game/${joinGameId}`);
}
}
}
}
fetchData();
}, [joinGameId, history]);
const handleSubmit = async (event: FormEvent) => {
event.preventDefault();
if (joinGameId) {
const res = await addPlayerToGame(joinGameId, playerName);
setIsGameFound(res);
if (res) {
history.push(`/game/${joinGameId}`);
}
}
};
return (
<Grow in={true} timeout={500}>
<div>
<form onSubmit={handleSubmit}>
<Card variant='outlined' className='JoinGameCard'>
<CardHeader
className='JoinGameCardHeader'
title='Join a Session'
titleTypographyProps={{ variant: 'h4' }}
/>
<CardContent className='JoinGameCardContent'>
<TextField
error={!gameFound}
helperText={!gameFound && 'Session not found, check the ID'}
className='JoinGameTextField'
required
id='filled-required'
label='Session ID'
placeholder='xyz...'
defaultValue={joinGameId}
variant='outlined'
onChange={(event: ChangeEvent<HTMLInputElement>) =>
setJoinGameId(event.target.value)
}
/>
<TextField
className='JoinGameTextField'
required
id='filled-required'
label='Your Name'
placeholder='Enter your name'
defaultValue={playerName}
variant='outlined'
onChange={(event: ChangeEvent<HTMLInputElement>) =>
setPlayerName(event.target.value)
}
/>
</CardContent>
<CardActions className='JoinGameCardAction'>
<Button
type='submit'
variant='contained'
color='primary'
className='JoinGameButton'
>
Join
</Button>
</CardActions>
</Card>
</form>
</div>
</Grow>
);
}
Example #29
Source File: index.tsx From aqualink-app with MIT License | 4 votes |
Satellite = ({ maxMonthlyMean, data, classes }: SatelliteProps) => {
const { dhw, satelliteTemperature, sstAnomaly } = data;
const degreeHeatingDays = { ...dhw, value: (dhw?.value || 0) * 7 };
const relativeTime =
satelliteTemperature?.timestamp &&
toRelativeTime(satelliteTemperature.timestamp);
const degreeHeatingWeeks = degreeHeatingWeeksCalculator(
degreeHeatingDays?.value
);
const metrics = [
{
label: "SURFACE TEMP",
value: `${formatNumber(satelliteTemperature?.value, 1)}°C`,
},
{
label: "HISTORICAL MAX",
value: `${formatNumber(maxMonthlyMean, 1)}°C`,
tooltipTitle: "Historical maximum monthly average over the past 20 years",
},
{
label: "DEGREE HEATING WEEKS",
value: formatNumber(degreeHeatingWeeks, 1),
tooltipTitle:
"Degree Heating Weeks - a measure of the amount of time above the 20 year historical maximum temperatures",
},
{
label: "SST ANOMALY",
tooltipTitle: "Difference between current SST and longterm average",
value: `${
sstAnomaly
? `${sstAnomaly.value > 0 ? "+" : ""}${formatNumber(
sstAnomaly.value,
1
)}`
: "- -"
}°C`,
},
];
return (
<Card
className={classes.root}
style={{ backgroundColor: dhwColorFinder(degreeHeatingWeeks) }}
>
<CardHeader
className={classes.header}
title={
<Grid container>
<Grid item>
<Typography className={classes.cardTitle} variant="h6">
SATELLITE OBSERVATION
</Typography>
</Grid>
</Grid>
}
/>
<CardContent className={classes.content}>
<Box p="1rem" display="flex" flexGrow={1}>
<Grid container spacing={1}>
{metrics.map(({ label, value, tooltipTitle }) => (
<Grid key={label} item xs={6}>
<Typography
className={classes.contentTextTitles}
variant="subtitle2"
>
{label}
</Typography>
<Tooltip title={tooltipTitle || ""}>
<Typography
className={classes.contentTextValues}
variant="h3"
>
{value}
</Typography>
</Tooltip>
</Grid>
))}
</Grid>
</Box>
<Grid container>
{dhwColorCode.map(({ value, color }) => (
<Grid
key={value}
item
xs={1}
style={{ backgroundColor: `${color}`, height: "2rem" }}
>
<Box textAlign="center">
<Typography variant="caption" align="center">
{value}
</Typography>
</Box>
</Grid>
))}
</Grid>
<UpdateInfo
relativeTime={relativeTime}
timeText="Last data received"
image={satellite}
imageText="NOAA"
live={false}
frequency="daily"
href="https://coralsitewatch.noaa.gov/"
/>
</CardContent>
</Card>
);
}