Skip to content

Commit

Permalink
feat(map): ✨ Claims on map, Information drawer
Browse files Browse the repository at this point in the history
  • Loading branch information
Nudelsuppe42 committed Oct 14, 2023
1 parent 971d819 commit c9c954a
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 112 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"eslint-import-resolver-webpack": "^0.13.2",
"flag-icons": "^6.6.6",
"framer-motion": "^10.6.1",
"geolib": "^3.3.4",
"i18next": "^21.10.0",
"keycloak-js": "^19.0.1",
"mapbox-gl": "^2.9.1",
Expand Down
37 changes: 37 additions & 0 deletions src/components/Stats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Group, Paper, PaperProps, Text } from '@mantine/core';

interface StatsGridProps {
title: string;
icon: any;
children: any;
subtitle?: string;
paperProps?: PaperProps;
isText?: boolean;
}

export function StatsGrid(data: StatsGridProps) {
return (
<Paper withBorder p="md" radius="md" key={data.title} {...data.paperProps}>
<Group justify="space-between">
<Text size="xs" c="dimmed" fw={700} style={{ textTransform: 'uppercase' }}>
{data.title}
</Text>
<data.icon size="1.4rem" stroke={1.5} className={'fs-dimmed'} />
</Group>

<Group align="flex-end" gap="xs" mt={25}>
{typeof data.children === 'string' || data.isText ? (
<Text size="xl" fw={700}>
{data.children}
</Text>
) : (
data.children
)}
</Group>

<Text fz="xs" c="dimmed" mt={7}>
{data.subtitle}
</Text>
</Paper>
);
}
117 changes: 117 additions & 0 deletions src/components/map/ClaimDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { Alert, Avatar, Button, Center, Drawer, Flex, Group, Loader, ScrollArea, Text } from '@mantine/core';
import {
Icon123,
IconBuilding,
IconCheck,
IconCopy,
IconCrane,
IconDotsCircleHorizontal,
IconPencil,
IconPin,
IconRuler2,
IconUser,
IconUsersGroup,
} from '@tabler/icons-react';

import { StatsGrid } from '../Stats';
import classes from '../styles/components/Card.module.css';
import { domainToASCII } from 'url';
import { getAreaOfPolygon } from 'geolib';
import { showNotification } from '@mantine/notifications';
import { useClipboard } from '@mantine/hooks';
import useSWR from 'swr';
import { useUser } from '../../hooks/useUser';

interface ClaimDrawerProps {
setOpen: (bool: boolean) => void;
open: boolean;
id: string | null;
}

export function ClaimDrawer(props: ClaimDrawerProps) {
const { data, isValidating } = useSWR('/claims/' + props.id);
const { user } = useUser();
const clipboard = useClipboard();

if (props.id == null) return <></>;

return (
<Drawer
opened={props.open}
onClose={() => props.setOpen(false)}
title={`Claim Details`}
size="md"
overlayProps={{ blur: 3 }}
lockScroll
scrollAreaComponent={ScrollArea.Autosize}
>
{isValidating || !data ? (
<Center h="100%" w="100%">
<Loader mt={'xl'} />
</Center>
) : (
<>
<StatsGrid title="Name" icon={IconPin} paperProps={{ mb: 'md' }}>
{data.name}
</StatsGrid>
{!data.finished && (
<Alert color="red" mb="md" radius="md" title="Claim Status" icon={<IconCrane />}>
This Claim is still under construction and not completed yet.
</Alert>
)}
<StatsGrid title="Team" icon={IconUsersGroup} paperProps={{ mb: 'md' }}>
<Flex justify="flex-start" align="center" direction="row" wrap="wrap" gap="md">
<Avatar src={data.buildTeam.icon} size={60} component="a" href={`/teams/${data.buildTeam.id}`} />
<Text size="xl" fw={700}>
{data.buildTeam.name}
</Text>
</Flex>
</StatsGrid>
<StatsGrid title="Owner" icon={IconUser} paperProps={{ mb: 'md' }}>
<Flex justify="flex-start" align="center" direction="row" wrap="wrap" gap="md">
<Avatar size={60}>{data.owner.name?.at(0)}</Avatar>
<Text size="xl" fw={700}>
{data.owner.name}
</Text>
</Flex>
</StatsGrid>
{data.builders && (
<StatsGrid title="Builders" icon={IconUsersGroup} paperProps={{ mb: 'md' }}>
<Avatar.Group>
{data.builders.slice(0, 4).map((b: any) => (
<Avatar key={b.id}>{b?.name?.at(0)}</Avatar>
))}
{data.builders.length > 4 && <Avatar>+{data.builders.length - 4}</Avatar>}
</Avatar.Group>
</StatsGrid>
)}
<StatsGrid title="Area" icon={IconRuler2} paperProps={{ mb: 'md' }} isText>
{Math.round(getAreaOfPolygon(data.area.map((p: string) => p.split(', ').map(Number)))).toLocaleString()}
</StatsGrid>
<Group grow>
<Button
leftSection={<IconCopy />}
onClick={() => {
const coords = data.center.split(', ');
clipboard.copy(coords[1] + ', ' + coords[0]);
showNotification({
title: 'Coordinates copied',
message: 'Paste them anywhere.',
icon: <IconCheck size={18} />,
color: 'teal',
});
}}
>
Copy Coordinates
</Button>
{data.owner?.id == user?.id && (
<Button component="a" variant="outline" leftSection={<IconPencil />} href={`/claims/${props.id}`}>
Edit Claim
</Button>
)}
</Group>
</>
)}
</Drawer>
);
}
Loading

0 comments on commit c9c954a

Please sign in to comment.