1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-10-13 11:17:26 +02:00

chore: improve project card design (#10418)

https://linear.app/unleash/issue/2-3728/remove-the-project-card-icon

Removes the project icon from our project cards. This gives us more
space for our project titles.

Also took the chance to better align the "activity" visual component,
since previously it was floating not-quite-in-the-middle of the card.

This is already aligned with UX and ready to go from that standpoint.

<img width="918" height="442" alt="image"
src="https://github.com/user-attachments/assets/1538511e-e70d-4632-9f67-7d6cd146aeca"
/>
This commit is contained in:
Nuno Góis 2025-07-28 12:57:33 +01:00 committed by GitHub
parent a6397c51ab
commit 8258ffcabe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 15 additions and 110 deletions

View File

@ -1,76 +0,0 @@
import { DEFAULT_PROJECT_ID } from 'hooks/api/getters/useDefaultProject/useDefaultProjectId';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import {
StyledProjectCard,
StyledDivHeader,
StyledBox,
StyledCardTitle,
StyledDivInfo,
StyledParagraphInfo,
StyledProjectCardBody,
StyledIconBox,
} from './ProjectCard.styles';
import { ProjectCardFooter } from './ProjectCardFooter/ProjectCardFooter.tsx';
import { ProjectModeBadge } from './ProjectModeBadge/ProjectModeBadge.tsx';
import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
import { FavoriteAction } from './FavoriteAction/FavoriteAction.tsx';
import type { ProjectSchema } from 'openapi';
import { Box } from '@mui/material';
export const ProjectCard = ({
name,
featureCount,
health,
memberCount = 0,
onHover,
id,
mode,
favorite = false,
owners,
}: ProjectSchema & { onHover?: () => void }) => (
<StyledProjectCard onMouseEnter={onHover}>
<StyledProjectCardBody>
<StyledDivHeader>
<StyledIconBox>
<ProjectIcon />
</StyledIconBox>
<StyledBox data-loading>
<StyledCardTitle>{name}</StyledCardTitle>
</StyledBox>
<ProjectModeBadge mode={mode} />
</StyledDivHeader>
<StyledDivInfo>
<div>
<StyledParagraphInfo data-loading>
{featureCount}
</StyledParagraphInfo>
<p data-loading>{featureCount === 1 ? 'flag' : 'flags'}</p>
</div>
<ConditionallyRender
condition={id !== DEFAULT_PROJECT_ID}
show={
<div>
<StyledParagraphInfo data-loading>
{memberCount}
</StyledParagraphInfo>
<p data-loading>
{memberCount === 1 ? 'member' : 'members'}
</p>
</div>
}
/>
<div>
<StyledParagraphInfo data-loading>
{health}%
</StyledParagraphInfo>
<p data-loading>healthy</p>
</div>
</StyledDivInfo>
</StyledProjectCardBody>
<ProjectCardFooter id={id} owners={owners}>
<Box sx={(theme) => ({ margin: theme.spacing(1, 2, 0, 0) })}>
<FavoriteAction id={id} isFavorite={favorite} />
</Box>
</ProjectCardFooter>
</StyledProjectCard>
);

View File

@ -4,13 +4,11 @@ import {
StyledBox, StyledBox,
StyledCardTitle, StyledCardTitle,
StyledProjectCardBody, StyledProjectCardBody,
StyledIconBox,
StyledActions, StyledActions,
} from './ProjectCard.styles'; } from './ProjectCard.styles';
import { ProjectCardFooter } from './ProjectCardFooter/ProjectCardFooter.tsx'; import { ProjectCardFooter } from './ProjectCardFooter/ProjectCardFooter.tsx';
import { ProjectModeBadge } from './ProjectModeBadge/ProjectModeBadge.tsx'; import { ProjectModeBadge } from './ProjectModeBadge/ProjectModeBadge.tsx';
import type { ProjectSchemaOwners } from 'openapi'; import type { ProjectSchemaOwners } from 'openapi';
import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
import { formatDateYMDHM } from 'utils/formatDate'; import { formatDateYMDHM } from 'utils/formatDate';
import { useLocationSettings } from 'hooks/useLocationSettings'; import { useLocationSettings } from 'hooks/useLocationSettings';
import { parseISO } from 'date-fns'; import { parseISO } from 'date-fns';
@ -72,9 +70,6 @@ export const ProjectArchiveCard: FC<ProjectArchiveCardProps> = ({
<StyledProjectCard disabled data-testid={id}> <StyledProjectCard disabled data-testid={id}>
<StyledProjectCardBody> <StyledProjectCardBody>
<StyledDivHeader> <StyledDivHeader>
<StyledIconBox>
<ProjectIcon color='action' />
</StyledIconBox>
<StyledBox data-loading> <StyledBox data-loading>
<Tooltip title={`id: ${id}`} arrow> <Tooltip title={`id: ${id}`} arrow>
<StyledTitle> <StyledTitle>

View File

@ -89,16 +89,6 @@ export const StyledParagraphInfo = styled('p')<{ disabled?: boolean }>(
}), }),
); );
export const StyledIconBox = styled(Box)(({ theme }) => ({
display: 'grid',
placeItems: 'center',
padding: theme.spacing(0, 0.5, 0, 1),
marginRight: theme.spacing(1),
alignSelf: 'baseline',
color: theme.palette.primary.main,
height: '100%',
}));
export const StyledActions = styled(Box)(({ theme }) => ({ export const StyledActions = styled(Box)(({ theme }) => ({
display: 'flex', display: 'flex',
margin: theme.spacing(0.5), margin: theme.spacing(0.5),

View File

@ -2,14 +2,12 @@ import {
StyledProjectCard, StyledProjectCard,
StyledCardTitle, StyledCardTitle,
StyledProjectCardBody, StyledProjectCardBody,
StyledIconBox,
} from './ProjectCard.styles'; } from './ProjectCard.styles';
import { ProjectCardFooter } from './ProjectCardFooter/ProjectCardFooter.tsx'; import { ProjectCardFooter } from './ProjectCardFooter/ProjectCardFooter.tsx';
import { ProjectModeBadge } from './ProjectModeBadge/ProjectModeBadge.tsx'; import { ProjectModeBadge } from './ProjectModeBadge/ProjectModeBadge.tsx';
import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
import { FavoriteAction } from './FavoriteAction/FavoriteAction.tsx'; import { FavoriteAction } from './FavoriteAction/FavoriteAction.tsx';
import { Box, styled } from '@mui/material'; import { Box, styled } from '@mui/material';
import { flexColumn } from 'themes/themeStyles'; import { flexColumn, flexRow } from 'themes/themeStyles';
import { TimeAgo } from 'component/common/TimeAgo/TimeAgo'; import { TimeAgo } from 'component/common/TimeAgo/TimeAgo';
import { ProjectLastSeen } from './ProjectLastSeen/ProjectLastSeen.tsx'; import { ProjectLastSeen } from './ProjectLastSeen/ProjectLastSeen.tsx';
import { Highlighter } from 'component/common/Highlighter/Highlighter'; import { Highlighter } from 'component/common/Highlighter/Highlighter';
@ -29,15 +27,15 @@ const StyledCount = styled('strong')(({ theme }) => ({
})); }));
const StyledInfo = styled('div')(({ theme }) => ({ const StyledInfo = styled('div')(({ theme }) => ({
display: 'grid', ...flexColumn,
gridTemplate: '1rem 1rem / 1fr 1fr',
gridAutoFlow: 'column',
alignItems: 'center',
justifyContent: 'space-between',
marginTop: theme.spacing(1),
fontSize: theme.fontSizes.smallerBody, fontSize: theme.fontSizes.smallerBody,
})); }));
const StyledContent = styled('div')({
...flexRow,
justifyContent: 'space-between',
});
const StyledHeader = styled('div')(({ theme }) => ({ const StyledHeader = styled('div')(({ theme }) => ({
gap: theme.spacing(1), gap: theme.spacing(1),
display: 'flex', display: 'flex',
@ -67,9 +65,6 @@ export const ProjectCard = ({
<StyledProjectCard onMouseEnter={onHover}> <StyledProjectCard onMouseEnter={onHover}>
<StyledProjectCardBody> <StyledProjectCardBody>
<StyledHeader> <StyledHeader>
<StyledIconBox>
<ProjectIcon />
</StyledIconBox>
<Box <Box
data-loading data-loading
sx={(theme) => ({ sx={(theme) => ({
@ -95,13 +90,14 @@ export const ProjectCard = ({
<StyledCount>{featureCount}</StyledCount> flag <StyledCount>{featureCount}</StyledCount> flag
{featureCount === 1 ? '' : 's'} {featureCount === 1 ? '' : 's'}
</div> </div>
<div data-loading> <StyledContent>
<StyledCount>{health}%</StyledCount> health <div data-loading>
</div> <StyledCount>{health}%</StyledCount> health
<div /> </div>
<div data-loading> <div data-loading>
<ProjectLastSeen date={lastReportedFlagUsage} /> <ProjectLastSeen date={lastReportedFlagUsage} />
</div> </div>
</StyledContent>
</StyledInfo> </StyledInfo>
</StyledProjectCardBody> </StyledProjectCardBody>
<ProjectCardFooter id={id} owners={owners}> <ProjectCardFooter id={id} owners={owners}>