images in badge popover

This commit is contained in:
yohlo
2025-10-06 02:23:25 -05:00
parent afd0b692fa
commit b458872ac1
2 changed files with 45 additions and 38 deletions

View File

@@ -1,4 +1,4 @@
import { Box, Container, Flex, Loader, useComputedColorScheme } from "@mantine/core";
import { Box, Container, Flex, Loader, Title, useComputedColorScheme } from "@mantine/core";
import { PropsWithChildren, Suspense, useEffect, useRef } from "react";
import { Drawer as VaulDrawer } from "vaul";
import styles from "./styles.module.css";
@@ -120,7 +120,7 @@ const Drawer: React.FC<DrawerProps> = ({
style={{ borderRadius: "9999px" }}
/>
<Container mx="auto" maw="28rem" px={0}>
<VaulDrawer.Title>{title}</VaulDrawer.Title>
<VaulDrawer.Title><Title order={2}>{title}</Title></VaulDrawer.Title>
<Suspense fallback={
<Flex justify='center' align='center' w='100%' h={400}>
<Loader size='lg' />

View File

@@ -1,4 +1,4 @@
import { Box, Text, Popover, Progress, Title, Image } from "@mantine/core";
import { Box, Text, Progress, Image, Popover, Title, Stack } from "@mantine/core";
import { usePlayerBadges, useAllBadges } from "../queries";
import { useAuth } from "@/contexts/auth-context";
import { Badge, BadgeProgress } from "../types";
@@ -21,7 +21,7 @@ interface BadgeIconProps {
earned: boolean;
}
const BadgeIcon = ({ badge, earned }: BadgeIconProps) => {
const BadgeIcon = ({ badge, earned, size = 48 }: BadgeIconProps & { size?: number }) => {
const [imageError, setImageError] = useState(false);
const imagePath = `/static/img/${badge.key}.png`;
@@ -29,13 +29,13 @@ const BadgeIcon = ({ badge, earned }: BadgeIconProps) => {
// Fallback to icon if image fails to load
return earned ? (
<MedalIcon
size={48}
size={size}
weight="fill"
color="var(--mantine-primary-color-6)"
/>
) : (
<LockKeyIcon
size={44}
size={size - 4}
weight="regular"
color="var(--mantine-color-dimmed)"
/>
@@ -46,8 +46,8 @@ const BadgeIcon = ({ badge, earned }: BadgeIconProps) => {
<Image
src={imagePath}
alt={badge.name}
width={48}
height={48}
width={size}
height={size}
onError={() => setImageError(true)}
style={{
objectFit: 'contain',
@@ -57,6 +57,7 @@ const BadgeIcon = ({ badge, earned }: BadgeIconProps) => {
);
};
const BadgeShowcase = ({ playerId }: BadgeShowcaseProps) => {
const { user } = useAuth();
const { data: badgeProgress } = usePlayerBadges(playerId);
@@ -164,7 +165,7 @@ const BadgeShowcase = ({ playerId }: BadgeShowcaseProps) => {
const showStack = stackCount > 1;
return (
<Popover key={display.badge.id} width={220} position="top" withArrow shadow="md">
<Popover key={display.badge.id} width={280} position="top" withArrow shadow="md" withinPortal>
<Popover.Target>
<Box
style={{
@@ -200,7 +201,7 @@ const BadgeShowcase = ({ playerId }: BadgeShowcaseProps) => {
width: '100px',
height: '100px',
borderRadius: '12px',
background: 'light-dark(var(--mantine-color-white), var(--mantine-color-dark-6))',
background: 'light-dark(var(--mantine-color-white), var(--mantine-color-dark-7))',
border: display.earned
? '2px solid var(--mantine-primary-color-6)'
: '2px dashed var(--mantine-primary-color-4)',
@@ -251,35 +252,41 @@ const BadgeShowcase = ({ playerId }: BadgeShowcaseProps) => {
</Box>
</Box>
</Popover.Target>
<Popover.Dropdown>
<Box>
<Title order={5}>
{display.badge.name}
</Title>
<Text size="xs" c="dimmed" mb={isCurrentUser ? "sm" : undefined}>
{display.badge.description}
</Text>
{isCurrentUser && (
<Box>
<Box mb="xs" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Text size="xs" fw={500} c="dimmed">
Progress
</Text>
<Text size="xs" fw={600} c="dimmed">
{display.progressText}
</Text>
</Box>
<Progress
value={(display.progress?.progress || 0) / getTargetProgress(display.badge) * 100}
size="sm"
radius="sm"
color={display.earned ? "green" : undefined}
/>
<Popover.Dropdown>
<Stack gap={4} align="center">
<Box style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<BadgeIcon badge={display.badge} earned={display.earned} size={80} />
</Box>
)}
</Box>
</Popover.Dropdown>
</Popover>
<Title order={5} ta="center">
{display.badge.name}
</Title>
<Text size="sm" c="dimmed" ta="center">
{display.badge.description}
</Text>
{isCurrentUser && (
<Box>
<Box mb="xs" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Text size="sm" fw={500} c="dimmed">
Progress&nbsp;
</Text>
<Text size="sm" fw={600} c="dimmed">
{display.progressText}
</Text>
</Box>
<Progress
value={(display.progress?.progress || 0) / getTargetProgress(display.badge) * 100}
size="sm"
radius="sm"
color={display.earned ? "green" : undefined}
/>
</Box>
)}
</Stack>
</Popover.Dropdown>
</Popover>
);
})}
</Box>