Skip to content

Commit a048512

Browse files
Merge pull request #26 from developmentseed/feature/global-ui
Flesh out global layout
2 parents 34ee4bc + db4f219 commit a048512

21 files changed

+1400
-299
lines changed

Diff for: package-lock.json

+8-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: packages/client/.env

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1+
# App metadata
12
APP_TITLE=STAC Manager
23
APP_DESCRIPTION=Plugin based STAC editor
4+
5+
# Api variables
36
REACT_APP_STAC_BROWSER=
4-
REACT_APP_STAC_API=
7+
REACT_APP_STAC_API=
8+
9+
## Theming
10+
# REACT_APP_THEME_PRIMARY_COLOR='#6A5ACD'
11+
# REACT_APP_THEME_SECONDARY_COLOR='#048A81'

Diff for: packages/client/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"lint": "yarn lint:scripts",
2525
"lint:scripts": "eslint app/",
2626
"ts-check": "yarn tsc --noEmit --skipLibCheck",
27-
"test": "echo \"Error: no test specified\" && exit 0"
27+
"test": "jest"
2828
},
2929
"engines": {
3030
"node": "20.x"
@@ -64,7 +64,7 @@
6464
"@stac-manager/data-plugins": "*",
6565
"@stac-manager/data-widgets": "*",
6666
"@testing-library/jest-dom": "^6.6.2",
67-
"@testing-library/react": "^16.0.1",
67+
"@testing-library/react": "^16.2.0",
6868
"@testing-library/user-event": "^14.5.2",
6969
"@turf/bbox": "^7.1.0",
7070
"@turf/bbox-polygon": "^7.1.0",

Diff for: packages/client/src/App.tsx

+6-10
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@ import { MainNavigation } from './components';
1818
import Home from './pages/Home';
1919
import CollectionList from './pages/CollectionList';
2020
import { CollectionForm } from './pages/CollectionForm';
21-
import ItemList from './pages/ItemList';
2221
import ItemDetail from './pages/ItemDetail';
23-
import ItemForm from './pages/ItemForm';
2422
import NotFound from './pages/NotFound';
2523
import CollectionDetail from './pages/CollectionDetail';
24+
import Sandbox from './pages/Sandbox';
2625
import { config } from './plugin-system/config';
2726

2827
export const App = () => (
@@ -31,17 +30,18 @@ export const App = () => (
3130
<PluginConfigProvider config={config}>
3231
<Router>
3332
<Container
34-
maxW='container.lg'
33+
maxW='container.xl'
3534
minH='100vh'
3635
display='flex'
3736
flexDirection='column'
37+
gap={4}
3838
>
3939
<Flex
4040
as='header'
4141
gap={4}
4242
alignItems='center'
4343
justifyContent='space-between'
44-
p={4}
44+
py={8}
4545
>
4646
<Heading as='p' size='sm'>
4747
STAC Manager
@@ -62,15 +62,11 @@ export const App = () => (
6262
path='/collections/:collectionId/edit/'
6363
element={<CollectionForm />}
6464
/>
65-
<Route path='/items/' element={<ItemList />} />
6665
<Route
6766
path='/collections/:collectionId/items/:itemId/'
6867
element={<ItemDetail />}
6968
/>
70-
<Route
71-
path='/collections/:collectionId/items/:itemId/edit/'
72-
element={<ItemForm />}
73-
/>
69+
<Route path='/sandbox' element={<Sandbox />} />
7470
<Route path='*' element={<NotFound />} />
7571
</Routes>
7672
</Box>
@@ -80,7 +76,7 @@ export const App = () => (
8076
alignItems='center'
8177
justifyContent='space-between'
8278
mt='auto'
83-
p={4}
79+
py={8}
8480
>
8581
<Flex gap={4} alignItems='center'>
8682
<Text as='span'>

Diff for: packages/client/src/components/InnerPageHeader.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const InnerPageHeader = forwardRef<InnerPageHeaderProps, 'div'>(
1414
ref={ref}
1515
bg='base.50'
1616
borderRadius='md'
17-
p={4}
17+
p={8}
1818
direction='column'
1919
gap={2}
2020
{...rest}
@@ -25,7 +25,7 @@ export const InnerPageHeader = forwardRef<InnerPageHeaderProps, 'div'>(
2525
</Text>
2626
)}
2727
<Flex gap={4} justifyContent='space-between' alignItems='center'>
28-
<Heading size='md' noOfLines={1}>
28+
<Heading size='lg' noOfLines={1} as='h1'>
2929
{title}
3030
</Heading>
3131
{actions && <Flex gap={2}>{actions}</Flex>}

Diff for: packages/client/src/components/ItemCard.tsx

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import React from 'react';
2+
import {
3+
Card,
4+
CardHeader,
5+
CardBody,
6+
CardFooter,
7+
Flex,
8+
Image,
9+
Text,
10+
Heading,
11+
Box,
12+
HStack,
13+
Tag,
14+
Skeleton,
15+
SkeletonText
16+
} from '@chakra-ui/react';
17+
import SmartLink from './SmartLink';
18+
19+
interface ItemCardProps {
20+
imageSrc?: string;
21+
imageAlt?: string;
22+
title?: string;
23+
subtitle?: string;
24+
description?: string;
25+
tags?: string[];
26+
to?: string;
27+
renderMenu?: () => React.ReactNode;
28+
}
29+
30+
export function ItemCard({
31+
imageSrc,
32+
imageAlt,
33+
title,
34+
subtitle,
35+
description,
36+
tags,
37+
to,
38+
renderMenu
39+
}: ItemCardProps) {
40+
const renderLink = (children: React.ReactNode) => {
41+
return to ? (
42+
<SmartLink to={to} color='inherit'>
43+
{children}
44+
</SmartLink>
45+
) : (
46+
<>{children}</>
47+
);
48+
};
49+
50+
return (
51+
<Card as='article' variant='filled'>
52+
{imageSrc &&
53+
renderLink(
54+
<Image
55+
src={imageSrc}
56+
alt={imageAlt}
57+
height='16rem'
58+
width='100%'
59+
objectFit='cover'
60+
borderRadius='md'
61+
/>
62+
)}
63+
<CardHeader as='header'>
64+
<Flex direction='row' gap={4}>
65+
{(title || subtitle) && (
66+
<Box flexBasis='100%'>
67+
{title && (
68+
<Heading size='sm' as='h3' wordBreak='break-word'>
69+
{renderLink(title)}
70+
</Heading>
71+
)}
72+
{subtitle && (
73+
<Text as='p' fontSize='sm' color='base.400'>
74+
{subtitle}
75+
</Text>
76+
)}
77+
</Box>
78+
)}
79+
{renderMenu && <Box>{renderMenu()}</Box>}
80+
</Flex>
81+
</CardHeader>
82+
{description && (
83+
<CardBody>
84+
<Text size='md'>{description}</Text>
85+
</CardBody>
86+
)}
87+
{tags && tags.length > 0 && (
88+
<CardFooter as='footer'>
89+
<HStack spacing={2} wrap='wrap'>
90+
{tags.map((tag) => (
91+
// <Tag key={tag} size='sm' colorScheme='primary' as='a' href='#'>
92+
<Tag key={tag} size='sm' colorScheme='primary'>
93+
{tag}
94+
</Tag>
95+
))}
96+
</HStack>
97+
</CardFooter>
98+
)}
99+
</Card>
100+
);
101+
}
102+
103+
export function ItemCardLoading(props: { mini?: boolean }) {
104+
return (
105+
<Card as='article' variant='filled' p={8}>
106+
<Flex direction='column' gap={2}>
107+
<Skeleton h={6} width='40%' />
108+
<Skeleton h={4} width='30%' />
109+
</Flex>
110+
111+
{!props.mini && (
112+
<>
113+
<SkeletonText mt={8} noOfLines={4} spacing='4' skeletonHeight='2' />
114+
<Flex gap={2} mt={12}>
115+
<Skeleton h={4} width={12} />
116+
<Skeleton h={4} width={12} />
117+
<Skeleton h={4} width={12} />
118+
</Flex>
119+
</>
120+
)}
121+
</Card>
122+
);
123+
}

Diff for: packages/client/src/components/MainNavigation.tsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ function MainNavigation() {
2929
<Box as='nav' aria-label='Main'>
3030
<List display='flex' gap={2}>
3131
<NavItem to='/collections/' leftIcon={<CollecticonFolder />}>
32-
Collections
33-
</NavItem>
34-
<NavItem to='/items/' leftIcon={<CollecticonFolder />}>
35-
Items
32+
Browse
3633
</NavItem>
3734
<NavItem to='/collections/new' leftIcon={<CollecticonPlusSmall />}>
3835
Create

Diff for: packages/client/src/components/Pagination.tsx

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React, { Dispatch, SetStateAction } from 'react';
2+
import { Button, ButtonGroup } from '@chakra-ui/react';
3+
4+
import { usePaginate } from '$utils/usePaginateHook';
5+
import { zeroPad } from '$utils/format';
6+
7+
interface PaginationProps {
8+
page: number;
9+
numPages: number;
10+
onPageChange: Dispatch<SetStateAction<number>>;
11+
}
12+
13+
export function Pagination(props: PaginationProps) {
14+
const { numPages, page, onPageChange } = props;
15+
const paginate = usePaginate({
16+
numPages,
17+
currentPage: page,
18+
onPageChange
19+
});
20+
21+
return (
22+
<ButtonGroup size='sm' variant='outline' isAttached>
23+
<Button onClick={paginate.goFirst} disabled={!paginate.hasPrevious}>
24+
First
25+
</Button>
26+
<Button onClick={paginate.goPrevious} disabled={!paginate.hasPrevious}>
27+
Previous
28+
</Button>
29+
{paginate.left.map((p) => (
30+
<Button key={p} onClick={() => paginate.goToPage(p)}>
31+
{zeroPad(p)}
32+
</Button>
33+
))}
34+
{paginate.hasLeftBreak && <Button disabled>...</Button>}
35+
{paginate.pages.map((p) => (
36+
<Button
37+
key={p}
38+
onClick={() => paginate.goToPage(p)}
39+
variant={p === page ? 'solid' : 'outline'}
40+
colorScheme={p === page ? 'primary' : undefined}
41+
>
42+
{zeroPad(p)}
43+
</Button>
44+
))}
45+
{paginate.hasRightBreak && <Button disabled>...</Button>}
46+
{paginate.right.map((p) => (
47+
<Button key={p} onClick={() => paginate.goToPage(p)}>
48+
{zeroPad(p)}
49+
</Button>
50+
))}
51+
<Button onClick={paginate.goNext} disabled={!paginate.hasNext}>
52+
Next
53+
</Button>
54+
<Button onClick={paginate.goLast} disabled={!paginate.hasNext}>
55+
Last
56+
</Button>
57+
</ButtonGroup>
58+
);
59+
}

Diff for: packages/client/src/components/StacBrowserMenuItem.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import SmartLink from './SmartLink';
55

66
const baseStacBrowserUrl =
77
process.env.REACT_APP_STAC_BROWSER ||
8-
'https://radiantearth.github.io/stac-browser/#/external';
8+
`https://radiantearth.github.io/stac-browser/#/external/${process.env.REACT_APP_STAC_API}`;
99

1010
export function StacBrowserMenuItem(
1111
props: MenuItemProps & { resourcePath: string }
@@ -15,7 +15,6 @@ export function StacBrowserMenuItem(
1515
<MenuItem
1616
icon={<CollecticonGlobe />}
1717
as={SmartLink}
18-
_hover={{ textDecoration: 'none' }}
1918
to={`${baseStacBrowserUrl}${resourcePath}`}
2019
{...rest}
2120
>

Diff for: packages/client/src/pages/CollectionDetail/CollectionMap.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ function CollectionMap({ collection }: CollectionMapProps) {
6464
}, [collection, map]);
6565

6666
return (
67-
<Map ref={setMapRef} dragPan={false} scrollZoom={false} cursor='default'>
67+
<Map ref={setMapRef}>
6868
<BackgroundTiles />
6969
{extent && (
7070
<Source id='extent' type='geojson' data={extent}>

0 commit comments

Comments
 (0)