Skip to content

Commit

Permalink
PIMS-1344: Properties Detailed View (#2214)
Browse files Browse the repository at this point in the history
Co-authored-by: Dylan Barkowsky <37922247+dbarkowsky@users.noreply.github.com>
  • Loading branch information
GrahamS-Quartech and dbarkowsky authored Feb 29, 2024
1 parent 1ac4ece commit 43fde0f
Show file tree
Hide file tree
Showing 14 changed files with 595 additions and 101 deletions.
11 changes: 11 additions & 0 deletions react-app/src/assets/icons/SidebarLeft-Linear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 18 additions & 15 deletions react-app/src/components/display/DataCard.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { columnNameFormatter, dateFormatter } from '@/utils/formatters';
import { Box, Button, CardContent, CardHeader, Divider, Typography } from '@mui/material';
import Card from '@mui/material/Card';
import React from 'react';
import React, { PropsWithChildren } from 'react';

interface IDataCard<T> {
type DataCardProps<T> = {
id?: string;
values: T;
title: string;
onEdit: () => void;
customFormatter?: (key: keyof T, value: any) => string | JSX.Element | undefined;
}
} & PropsWithChildren;

const DataCard = <T,>(props: IDataCard<T>) => {
const DataCard = <T,>(props: DataCardProps<T>) => {
const { values, title, customFormatter, onEdit } = props;

const defaultFormatter = (key: keyof T, val: any) => {
Expand All @@ -29,6 +30,7 @@ const DataCard = <T,>(props: IDataCard<T>) => {
return (
<Card variant="outlined" sx={{ padding: '2rem', minWidth: '34rem', backgroundColor: 'white' }}>
<CardHeader
id={props.id}
titleTypographyProps={{ variant: 'h1' }}
sx={{
'.MuiCardHeader-action': {
Expand All @@ -49,17 +51,18 @@ const DataCard = <T,>(props: IDataCard<T>) => {
}
/>
<CardContent>
{Object.keys(values).map((key, idx) => (
<React.Fragment key={`card-data-fragment-${idx}-${key}`}>
<Box display={'flex'} flexDirection={'row'}>
<Typography width={'150px'} fontWeight={'bold'}>
{columnNameFormatter(key)}
</Typography>
{defaultFormatter(key as keyof T, values[key])}
</Box>
{idx < Object.keys(values).length - 1 && <Divider sx={{ mt: '1rem', mb: '1rem' }} />}
</React.Fragment>
))}
{props.children ??
Object.keys(values).map((key, idx) => (
<React.Fragment key={`card-data-fragment-${idx}-${key}`}>
<Box display={'flex'} flexDirection={'row'}>
<Typography width={'150px'} fontWeight={'bold'}>
{columnNameFormatter(key)}
</Typography>
{defaultFormatter(key as keyof T, values[key])}
</Box>
{idx < Object.keys(values).length - 1 && <Divider sx={{ mt: '1rem', mb: '1rem' }} />}
</React.Fragment>
))}
</CardContent>
</Card>
);
Expand Down
39 changes: 39 additions & 0 deletions react-app/src/components/display/DetailViewNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import Icon from '@mdi/react';
import { Box, IconButton, Avatar, Typography, Button, ButtonProps, useTheme } from '@mui/material';
import { mdiArrowLeft } from '@mdi/js';

interface IDetailViewNavigation {
navigateBackTitle: string;
deleteTitle: string;
onDeleteClick: () => void;
onBackClick: () => void;
deleteButtonProps?: ButtonProps;
}

const DetailViewNavigation = (props: IDetailViewNavigation) => {
const theme = useTheme();
const { navigateBackTitle, deleteTitle, onDeleteClick, onBackClick, deleteButtonProps } = props;
return (
<Box display={'flex'} alignItems={'center'}>
<IconButton onClick={() => onBackClick()}>
<Avatar
style={{ color: 'white', backgroundColor: 'white' }} //For some reason this doesn't get applied if you do it in sx props.
sx={{ border: '0.1px solid lightgray' }}
>
<Icon color="black" size={0.9} path={mdiArrowLeft} />
</Avatar>
</IconButton>
<Typography variant="h5">{navigateBackTitle}</Typography>
<Button
onClick={() => onDeleteClick()}
sx={{ fontWeight: 'bold', color: theme.palette.warning.main, marginLeft: 'auto' }}
{...deleteButtonProps}
>
{deleteTitle}
</Button>
</Box>
);
};

export default DetailViewNavigation;
3 changes: 2 additions & 1 deletion react-app/src/components/layout/BaseLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { PropsWithChildren } from 'react';
import { Box } from '@mui/material';
import { Box, Toolbar } from '@mui/material';
import Header from '@/components/layout/Header';
import Footer from '@/components/layout/Footer';

Expand All @@ -17,6 +17,7 @@ const BaseLayout = (props: IBaseLayoutProps) => {
}}
>
<Header />
<Toolbar />
<Box component="main" flex="1 1 auto">
{props.children}
</Box>
Expand Down
114 changes: 114 additions & 0 deletions react-app/src/components/layout/CollapsibleSidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import sideBarIcon from '@/assets/icons/SidebarLeft-Linear.svg';
import {
Avatar,
Box,
CSSObject,
Drawer,
Icon,
IconButton,
ListItem,
ListItemButton,
ListItemText,
Theme,
useTheme,
} from '@mui/material';
import React, { PropsWithChildren, useState } from 'react';

interface ISideBarItem {
title: string;
subTitle?: string;
}

type ICollapsibleSidebar = {
items: ISideBarItem[];
} & PropsWithChildren;

const CollapsibleSidebar = (props: ICollapsibleSidebar) => {
const openWidth = '300px';
const closedWidth = 'calc(52px + 2rem)';
const openedMixin = (theme: Theme): CSSObject => ({
width: openWidth,
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
overflowX: 'hidden',
});

const closedMixin = (theme: Theme): CSSObject => ({
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
overflowX: 'hidden',
width: closedWidth,
});

const [drawerOpen, setDrawerOpen] = useState(true);
const theme = useTheme();
return (
<Box>
<Drawer
variant="permanent"
anchor="left"
open={drawerOpen}
sx={{
width: drawerOpen ? openWidth : closedWidth,
flexShrink: 0,
[`& .MuiDrawer-paper`]: {
width: drawerOpen ? openWidth : closedWidth,
boxSizing: 'border-box',
},
...(drawerOpen && {
...openedMixin(theme),
'& .MuiDrawer-paper': openedMixin(theme),
}),
...(!drawerOpen && {
...closedMixin(theme),
'& .MuiDrawer-paper': closedMixin(theme),
}),
}}
>
<Box display={'flex'} sx={{ ml: '1rem', mt: '88px', mr: '1rem' }}>
<IconButton onClick={() => setDrawerOpen(!drawerOpen)}>
<Avatar
style={{
backgroundColor: '#eee',
height: 36,
width: 36,
}}
>
<Icon sx={{ mb: '2px' }}>
<img
height={18}
width={18}
src={sideBarIcon}
style={{ transform: `rotate(${drawerOpen ? '3.142rad' : '0'})` }}
/>
</Icon>
</Avatar>
</IconButton>
</Box>
<Box>
{drawerOpen &&
props.items.map((item) => (
<ListItem key={item.title}>
<ListItemButton
onClick={() => {
const element = document.getElementById(item.title);
const y = element.getBoundingClientRect().top + window.scrollY + -74;
window.scrollTo({ top: y, behavior: 'smooth' });
}}
>
<ListItemText primary={item.title} secondary={item.subTitle} />
</ListItemButton>
</ListItem>
))}
</Box>
</Drawer>
<Box ml={drawerOpen ? openWidth : closedWidth}>{props.children}</Box>
</Box>
);
};

export default CollapsibleSidebar;
4 changes: 3 additions & 1 deletion react-app/src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,16 @@ const Header: React.FC = () => {
return (
<AppBar
elevation={0}
component={'nav'}
style={{
backgroundColor: theme.palette.white.main,
height: '74px',
display: 'flex',
position: 'relative',
position: 'fixed',
justifyContent: 'center',
borderBottom: '1px solid',
borderBottomColor: theme.palette.gray.main,
zIndex: theme.zIndex.drawer + 1,
}}
>
<Toolbar>
Expand Down
39 changes: 36 additions & 3 deletions react-app/src/components/property/ClassificationIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Avatar, Badge, Icon } from '@mui/material';
import { Avatar, Badge, Box, Icon, Typography } from '@mui/material';
import BuildingIcon from '@/assets/icons/building.svg';
import ParcelIcon from '@/assets/icons/parcel.svg';

Expand All @@ -13,7 +13,7 @@ type ClassificationIconType = {
scale?: number;
};

const ClassificationIcon = (props: ClassificationIconType) => {
export const ClassificationIcon = (props: ClassificationIconType) => {
const { amount, iconType, textColor, backgroundColor, scale } = props;
const internalScale = scale ?? 1;
return (
Expand Down Expand Up @@ -45,4 +45,37 @@ const ClassificationIcon = (props: ClassificationIconType) => {
);
};

export default ClassificationIcon;
interface IClassificationInline {
color: string;
backgroundColor: string;
title: string;
}

export const ClassificationInline = (props: IClassificationInline) => {
return (
<Box display={'flex'} flexDirection={'row'} alignItems={'center'} gap={'12px'}>
<Box
display={'flex'}
alignItems={'center'}
justifyContent={'center'}
sx={{
width: '16px',
height: '16px',
borderRadius: '50%',
backgroundColor: props.backgroundColor,
}}
>
<Box
sx={{
width: '8px',
height: '8px',
borderRadius: '50%',
opacity: '100%',
backgroundColor: props.color,
}}
></Box>
</Box>
<Typography fontSize={'0.8rem'}>{props.title}</Typography>
</Box>
);
};
56 changes: 56 additions & 0 deletions react-app/src/components/property/ParcelNetValueTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { dateFormatter } from '@/utils/formatters';
import { DataGrid, GridColDef } from '@mui/x-data-grid';
import React from 'react';

const ParcelNetValueTable = () => {
const columns: GridColDef[] = [
{
field: 'FiscalYear',
headerName: 'Year',
},
{
field: 'EffectiveDate',
headerName: 'Effective Date',
flex: 1,
},
{
field: 'Value',
headerName: 'Net Book Value',
flex: 1,
},
];

const testData = [
{
FiscalYear: '24/23',
EffectiveDate: dateFormatter(new Date()),
Value: '$34000000',
},
{
FiscalYear: '23/22',
EffectiveDate: dateFormatter(new Date()),
Value: '$145000000',
},
];

return (
<DataGrid
sx={{
borderStyle: 'none',
'& .MuiDataGrid-columnHeaders': {
borderBottom: 'none',
},
'& div div div div >.MuiDataGrid-cell': {
borderBottom: 'none',
borderTop: '1px solid rgba(224, 224, 224, 1)',
},
}}
hideFooter
getRowId={(row) => row.FiscalYear}
columns={columns}
rows={testData}
/>
);
};

export default ParcelNetValueTable;
Loading

0 comments on commit 43fde0f

Please sign in to comment.