Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose beneficiary information in credit transactions table #59

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
75 changes: 75 additions & 0 deletions components/beneficiary-heading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Input } from '@carbonplan/components'
import { useEffect, useState } from 'react'
import { Box } from 'theme-ui'

import IconWrapper from './icon-wrapper'
import { useQueries } from './queries'

const SearchCircle = ({ ...props }) => {
const style = { vectorEffect: 'non-scaling-stroke' }

return (
<Box
as='svg'
viewBox='0 0 24 24'
fill='none'
width='24'
height='24'
stroke='currentColor'
strokeWidth='1.5'
{...props}
>
<path
style={style}
d='M12 23.0769C18.1176 23.0769 23.0769 18.1176 23.0769 12C23.0769 5.88239 18.1176 0.92308 12 0.92308C5.88239 0.92308 0.92308 5.88239 0.92308 12C0.92308 18.1176 5.88239 23.0769 12 23.0769Z'
/>
<path style={style} d='M7 17L11 13' />
<path
style={style}
d='M13.5 14C15.433 14 17 12.433 17 10.5C17 8.567 15.433 7 13.5 7C11.567 7 10 8.567 10 10.5C10 12.433 11.567 14 13.5 14Z'
/>
</Box>
)
}

const BeneficiaryHeading = ({ sx, color }) => {
const { beneficiarySearch, setBeneficiarySearch } = useQueries()
const [value, setValue] = useState(beneficiarySearch)

// Store input value in component state for performance reasons,
// but update context via useEffect here.
useEffect(() => {
setBeneficiarySearch(value)
}, [value])

return (
<IconWrapper
sx={sx}
buttonBehavior
initiallyExpanded={!!beneficiarySearch}
Icon={SearchCircle}
color={color}
onClose={() => setValue('')}
content={
<Input
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder='enter search term'
name='beneficiary search'
color={color}
size='xs'
sx={{
fontSize: 1,
fontFamily: 'mono',
width: '100%',
borderBottom: 0,
}}
/>
}
>
Beneficiary
</IconWrapper>
)
}

export default BeneficiaryHeading
51 changes: 38 additions & 13 deletions components/credit-row.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,22 @@ import Quantity from './quantity'
import { TableRow } from './table'

const CreditRow = ({ color, event, projectView, ...props }) => {
const { project_id, transaction_date, transaction_type, quantity, vintage } =
event
const {
project_id,
transaction_date,
transaction_type,
quantity,
vintage,
retirement_account,
retirement_beneficiary,
retirement_note,
retirement_reason,
} = event

return (
<>
<TableRow
columns={[6, 6, 6, 6]}
columns={[6, 6, 7, 7]}
values={[
{
key: 'transaction_date',
Expand All @@ -28,7 +37,19 @@ const CreditRow = ({ color, event, projectView, ...props }) => {
) : (
'?'
),
width: 2,
width: [1, 1, 2, 2],
},
{
key: 'quantity',
label: (
<Flex sx={{ gap: 2 }}>
<Quantity color={color} value={quantity} />
<Box sx={{ display: ['inherit', 'none', 'none', 'none'] }}>
{transaction_type === 'retirement' ? 'retired' : 'issued'}
</Box>
</Flex>
),
width: [2, 1, 1, 1],
},
{
key: 'vintage',
Expand All @@ -42,7 +63,7 @@ const CreditRow = ({ color, event, projectView, ...props }) => {
{transaction_type}
</Text>
),
width: [0, 2, 2, 2],
width: [0, 1, 1, 1],
},
...(projectView
? []
Expand All @@ -66,16 +87,20 @@ const CreditRow = ({ color, event, projectView, ...props }) => {
},
]),
{
key: 'quantity',
key: 'beneficiary',
label: (
<Flex sx={{ gap: 3 }}>
<Quantity color={color} value={quantity} />
<Box sx={{ display: ['inherit', 'none', 'none', 'none'] }}>
{transaction_type === 'retirement' ? 'retired' : 'issued'}
</Box>
</Flex>
<Text>
{retirement_account ??
retirement_beneficiary ??
retirement_note ??
retirement_reason ?? (
<Text sx={{ opacity: 0.5 }}>
{transaction_type === 'issuance' ? 'N/A' : 'None listed'}
</Text>
)}
</Text>
),
width: [2, 1, 1, 1],
width: 2,
},
]}
{...props}
Expand Down
60 changes: 41 additions & 19 deletions components/credits.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import useFetcher from './use-fetcher'
import CreditRow from './credit-row'
import Pagination from './pagination'
import TooltipWrapper from './tooltip-wrapper'
import BeneficiaryHeading from './beneficiary-heading'

const sx = {
footerLabel: {
Expand All @@ -34,8 +35,14 @@ const sx = {
}

const Credits = ({ project_id, color, borderTop = true }) => {
const { registry, category, complianceOnly, search, transactionBounds } =
useQueries()
const {
registry,
category,
complianceOnly,
search,
beneficiarySearch,
transactionBounds,
} = useQueries()
const [sort, setSort] = useState('-transaction_date')
const [page, setPage] = useState(1)
const { data, error, isLoading } = useFetcher('credits/', {
Expand All @@ -51,13 +58,21 @@ const Credits = ({ project_id, color, borderTop = true }) => {

useEffect(() => {
setPage(1)
}, [sort, transactionBounds, registry, category, complianceOnly, search])
}, [
sort,
transactionBounds,
registry,
category,
complianceOnly,
search,
beneficiarySearch,
])

return (
<Box as='table' sx={{ width: '100%' }}>
<TableHead
color={color}
columns={[6, 6, 6, 6]}
columns={[6, 6, 7, 7]}
sort={sort}
setSort={setSort}
values={[
Expand All @@ -72,7 +87,12 @@ const Credits = ({ project_id, color, borderTop = true }) => {
Date
</TooltipWrapper>
),
width: 2,
width: [1, 1, 2, 2],
},
{
value: 'quantity',
label: 'Quantity',
width: [2, 1, 1, 1],
},
{
value: 'vintage',
Expand All @@ -87,12 +107,16 @@ const Credits = ({ project_id, color, borderTop = true }) => {
{
value: 'transaction_type',
label: 'Type',
width: [0, 2, 2, 2],
width: [0, 1, 1, 1],
},
...(project_id
? []
: [{ value: 'project_id', label: 'Project ID', width: 2 }]),
{ value: 'quantity', label: 'Quantity', width: 1 },
{
value: 'beneficiary',
label: <BeneficiaryHeading sx={sx.tooltip} color={color} />,
width: 2,
},
]}
borderTop={borderTop}
/>
Expand All @@ -108,13 +132,13 @@ const Credits = ({ project_id, color, borderTop = true }) => {
))}
{data.data.length === 0 ? (
<TableRow
columns={[6, 6, 6, 6]}
columns={[6, 6, 7, 7]}
sx={{ minHeight: [0, 200, 200, 200] }}
values={[
{
label: 'No results found',
key: 'empty',
width: [6, 6, 6, 6],
width: [6, 6, 7, 7],
},
]}
/>
Expand All @@ -125,20 +149,20 @@ const Credits = ({ project_id, color, borderTop = true }) => {
{isLoading && (
<FadeIn as='tbody'>
<LoadingState
columns={[6, 6, 6, 6]}
columns={[6, 6, 7, 7]}
values={[
{ key: 'transaction_date', width: 2 },
{ key: 'transaction_date', width: [1, 1, 2, 2] },
{ key: 'quantity', width: 1 },
{
value: 'vintage',
width: [project_id ? 1 : 0, 1, 1, 1],
},

{
key: 'transaction_type',
width: [0, 2, 2, 2],
width: [0, 1, 1, 1],
},
{ key: 'beneficiary', width: 2 },
...(project_id ? [] : [{ key: 'project_id', width: 2 }]),
{ key: 'quantity', width: 1 },
]}
/>
</FadeIn>
Expand All @@ -149,16 +173,14 @@ const Credits = ({ project_id, color, borderTop = true }) => {
</FadeIn>
)}
<TableFoot
columns={[6, 6, 6, 6]}
columns={[6, 6, 7, 7]}
values={[
{
label: (
<Flex sx={sx.footerLabel}>
Total
Count
<Badge sx={{ color, whiteSpace: 'nowrap', flexShrink: 0 }}>
{unfilteredData
? formatValue(unfilteredData.pagination.total_entries)
: '-'}
{data ? formatValue(data.pagination.total_entries) : '-'}
</Badge>
</Flex>
),
Expand Down
Loading
Loading