improve favorite / rating display on item card

This commit is contained in:
jeffvli
2025-12-01 20:04:40 -08:00
parent 72e7006cc3
commit 93d4536ba6
3 changed files with 72 additions and 16 deletions
@@ -116,16 +116,22 @@
right: 0; right: 0;
} }
.favorite {
svg {
stroke: white;
stroke-width: 1.5px;
}
}
.rating { .rating {
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
padding: var(--theme-spacing-md); padding: var(--theme-spacing-md);
@mixin light { svg {
svg { stroke: white;
stroke: var(--theme-colors-background); stroke-width: 1.5px;
}
} }
} }
@@ -55,15 +55,42 @@
.favorite-badge { .favorite-badge {
position: absolute; position: absolute;
top: 0; top: -50px;
left: 0; left: -50px;
z-index: 2; width: 80px;
width: 0; height: 80px;
height: 0;
pointer-events: none; pointer-events: none;
border-color: var(--theme-colors-primary) transparent transparent transparent; background-color: var(--theme-colors-primary);
border-style: solid; box-shadow: 0 0 10px 8px rgb(0 0 0 / 80%);
border-width: 24px 24px 0 0; opacity: 1;
transform: rotate(-45deg);
transition: opacity 0.2s ease-in-out;
}
.rating-badge {
position: absolute;
top: var(--theme-spacing-sm);
right: var(--theme-spacing-sm);
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
padding: var(--theme-spacing-xs) var(--theme-spacing-sm);
font-size: var(--theme-font-size-md);
font-weight: 600;
color: var(--theme-colors-foreground);
text-shadow: 0 1px 2px rgb(0 0 0 / 80%);
pointer-events: none;
background-color: var(--theme-colors-primary);
border-radius: var(--theme-radius-md);
box-shadow: 0 2px 8px rgb(0 0 0 / 50%);
opacity: 1;
transition: opacity 0.2s ease-in-out;
}
.image-container:hover .favorite-badge,
.image-container:hover .rating-badge {
opacity: 0;
} }
.image { .image {
@@ -232,20 +232,29 @@ const CompactItemCard = ({
e.stopPropagation(); e.stopPropagation();
}; };
const isFavorite =
'userFavorite' in data && (data as { userFavorite: boolean }).userFavorite;
const userRating =
'userRating' in data &&
typeof (data as { userRating: null | number }).userRating === 'number'
? (data as { userRating: null | number }).userRating
: null;
const hasRating = userRating !== null && userRating > 0;
const imageContainerClassName = clsx(styles.imageContainer, { const imageContainerClassName = clsx(styles.imageContainer, {
[styles.isRound]: isRound, [styles.isRound]: isRound,
}); });
const isFavorite =
'userFavorite' in data && (data as { userFavorite: boolean }).userFavorite;
const imageContainerContent = ( const imageContainerContent = (
<> <>
<Image <Image
className={clsx(styles.image, { [styles.isRound]: isRound })} className={clsx(styles.image, {
[styles.isRound]: isRound,
})}
src={imageUrl} src={imageUrl}
/> />
{isFavorite && <div className={styles.favoriteBadge} />} {isFavorite && <div className={styles.favoriteBadge} />}
{hasRating && <div className={styles.ratingBadge}>{userRating}</div>}
<AnimatePresence> <AnimatePresence>
{withControls && showControls && ( {withControls && showControls && (
<ItemCardControls <ItemCardControls
@@ -443,6 +452,12 @@ const DefaultItemCard = ({
const isFavorite = const isFavorite =
'userFavorite' in data && (data as { userFavorite: boolean }).userFavorite; 'userFavorite' in data && (data as { userFavorite: boolean }).userFavorite;
const userRating =
'userRating' in data &&
typeof (data as { userRating: null | number }).userRating === 'number'
? (data as { userRating: null | number }).userRating
: null;
const hasRating = userRating !== null && userRating > 0;
const imageContainerContent = ( const imageContainerContent = (
<> <>
@@ -451,6 +466,7 @@ const DefaultItemCard = ({
src={imageUrl} src={imageUrl}
/> />
{isFavorite && <div className={styles.favoriteBadge} />} {isFavorite && <div className={styles.favoriteBadge} />}
{hasRating && <div className={styles.ratingBadge}>{userRating}</div>}
<AnimatePresence> <AnimatePresence>
{withControls && showControls && ( {withControls && showControls && (
<ItemCardControls <ItemCardControls
@@ -695,6 +711,12 @@ const PosterItemCard = ({
const isFavorite = const isFavorite =
'userFavorite' in data && (data as { userFavorite: boolean }).userFavorite; 'userFavorite' in data && (data as { userFavorite: boolean }).userFavorite;
const userRating =
'userRating' in data &&
typeof (data as { userRating: null | number }).userRating === 'number'
? (data as { userRating: null | number }).userRating
: null;
const hasRating = userRating !== null && userRating > 0;
const imageContainerContent = ( const imageContainerContent = (
<> <>
@@ -703,6 +725,7 @@ const PosterItemCard = ({
src={imageUrl} src={imageUrl}
/> />
{isFavorite && <div className={styles.favoriteBadge} />} {isFavorite && <div className={styles.favoriteBadge} />}
{hasRating && <div className={styles.ratingBadge}>{userRating}</div>}
<AnimatePresence> <AnimatePresence>
{withControls && showControls && data && ( {withControls && showControls && data && (
<ItemCardControls <ItemCardControls