Skip to content

Commit

Permalink
feat: add subsidized tags and dropdown filter
Browse files Browse the repository at this point in the history
* Add 'Subsidized' and 'Partially Subsidized' tags to Realtoken Dashboard for enhanced property status clarity - resolves #8

* add translation

* Add subsidized rent dopdown fileter - resolves #13

* Small translation adjustment

* fix: an asset without subsidy value is not subsidized

* fix: disable subsidy filter by default

Relies #8, #13
  • Loading branch information
NandyBa authored Oct 1, 2023
1 parent dc286df commit da37267
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 3 deletions.
70 changes: 70 additions & 0 deletions src/components/assetsView/AssetsSubsidyFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'

import { Select } from '@mantine/core'

import { useAtom } from 'jotai'

import { assetSubsidyChoosedAtom } from 'src/states'
import { Realtoken } from 'src/store/features/realtokens/realtokensSelector'

import { useInputStyles } from '../inputs/useInputStyles'
import { AssetSubsidyType } from './types'

export const AssetsSubsidyFilter: FC = () => {
const { t } = useTranslation('common', { keyPrefix: 'assetSubsidy' })
const { classes: inputClasses } = useInputStyles()

const [choosenSubsidyType, setChoosenSubsidyType] = useAtom(
assetSubsidyChoosedAtom
)

const viewOptions = [
{
value: AssetSubsidyType.ALL,
label: t('options.all'),
},
{
value: AssetSubsidyType.FULLY_SUBSIDIZED,
label: t('options.fullySubsidized'),
},
{
value: AssetSubsidyType.SUBSIDIZED,
label: t('options.subsidized'),
},
{
value: AssetSubsidyType.NOT_SUBSIDIZED,
label: t('options.notSubsidized'),
},
]

return (
<Select
label={t('label')}
data={viewOptions}
value={choosenSubsidyType}
onChange={(value: AssetSubsidyType) =>
value && setChoosenSubsidyType(value)
}
classNames={inputClasses}
/>
)
}
AssetsSubsidyFilter.displayName = 'AssetsSubsidyFilter'

export function useAssetsSubsidyFilter() {
const [choosenSubsidyType] = useAtom(assetSubsidyChoosedAtom)

return (asset: Realtoken) => {
switch (choosenSubsidyType) {
case AssetSubsidyType.FULLY_SUBSIDIZED:
return asset.subsidyStatus === 'yes' && !!asset.subsidyStatusValue
case AssetSubsidyType.SUBSIDIZED:
return asset.subsidyStatus !== 'no' && !!asset.subsidyStatusValue
case AssetSubsidyType.NOT_SUBSIDIZED:
return !asset.subsidyStatus || asset.subsidyStatus === 'no'
default:
return true
}
}
}
22 changes: 20 additions & 2 deletions src/components/assetsView/AssetsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import { selectOwnedRealtokens } from 'src/store/features/wallets/walletsSelecto

import { AssetsSearch, useAssetsSearch } from './AssetsSearch'
import { AssetsSort, useAssetsSort } from './AssetsSort'
import {
AssetsSubsidyFilter,
useAssetsSubsidyFilter,
} from './AssetsSubsidyFilter'
import { AssetsViewSelect, useAssetsViewSelect } from './assetsViewSelect'
import { AssetViewType } from './types'
import { AssetGrid, AssetTable } from './views'
Expand All @@ -18,9 +22,20 @@ export const AssetsView: FC = () => {

const realtokens = useSelector(selectOwnedRealtokens)

const assetSubsidyFilterFunction = useAssetsSubsidyFilter()

const data = useMemo(
() => realtokens.filter(assetSearchFunction).sort(assetSortFunction),
[realtokens, assetSearchFunction, assetSortFunction]
() =>
realtokens
.filter(assetSearchFunction)
.filter(assetSubsidyFilterFunction)
.sort(assetSortFunction),
[
realtokens,
assetSearchFunction,
assetSortFunction,
assetSubsidyFilterFunction,
]
)

return (
Expand All @@ -38,6 +53,9 @@ export const AssetsView: FC = () => {
<AssetsSort />
</Flex>
</Grid.Col>
<Grid.Col xs={12} sm={'content'}>
<AssetsSubsidyFilter />
</Grid.Col>
<Grid.Col xs={12} sm={'content'}>
<AssetsViewSelect />
</Grid.Col>
Expand Down
6 changes: 6 additions & 0 deletions src/components/assetsView/types/assetSubsidy.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum AssetSubsidyType {
FULLY_SUBSIDIZED = 'fullySubsidized',
SUBSIDIZED = 'Subsidized',
NOT_SUBSIDIZED = 'notSubsidized',
ALL = 'all',
}
1 change: 1 addition & 0 deletions src/components/assetsView/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './assetSort.type'
export * from './assetView.type'
export * from './assetSubsidy.type'
3 changes: 2 additions & 1 deletion src/components/cards/AssetCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Badge, Button, Card, Group, createStyles } from '@mantine/core'

import { OwnedRealtoken } from 'src/store/features/wallets/walletsSelector'

import { Divider, RentStatusTag, RmmStatusTag } from '../commons'
import { Divider, RentStatusTag, RmmStatusTag, SubsidyStatusTag } from '../commons'

const useStyles = createStyles({
imageContainer: {
Expand Down Expand Up @@ -80,6 +80,7 @@ const AssetCardComponent: FC<{ value: OwnedRealtoken }> = (props) => {

<Group position={'left'} mt={'xs'}>
<RentStatusTag value={props.value} />
<SubsidyStatusTag value={props.value} />
{props.value.isRmmAvailable ? <RmmStatusTag /> : null}
</Group>

Expand Down
33 changes: 33 additions & 0 deletions src/components/commons/assets/SubsidyStatusTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'

import { Badge } from '@mantine/core'

import { OwnedRealtoken } from 'src/store/features/wallets/walletsSelector'

export const SubsidyStatusTag: FC<{ value: OwnedRealtoken }> = (props) => {
const { t } = useTranslation('common', { keyPrefix: 'assetCard' })
const { subsidyStatus, subsidyStatusValue } = props.value

if (!subsidyStatusValue) {
return <></>
}

switch (subsidyStatus) {
case 'yes':
return (
<Badge size={'xs'} variant={'dot'} color={'blue'}>
{t('subsidyStatus.full')}
</Badge>
)
case 'partial':
return (
<Badge size={'xs'} variant={'filled'} color={'cyan.4'}>
{t('subsidyStatus.partial')}
</Badge>
)
default:
return <></>
}
}
SubsidyStatusTag.displayName = 'SubsidyStatusTag'
1 change: 1 addition & 0 deletions src/components/commons/assets/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './RentStatusTag'
export * from './RmmStatusTag'
export * from './SubsidyStatusTag'
13 changes: 13 additions & 0 deletions src/i18next/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@
"grid": "Grid"
}
},
"assetSubsidy": {
"label": "Subsidized rent",
"options": {
"all": "No filtered",
"fullySubsidized": "Fully subsidized",
"subsidized": "Subsidized",
"notSubsidized": "Not subsidized"
}
},
"assetCard": {
"tokens": "Tokens",
"apr": "APR",
Expand All @@ -88,6 +97,10 @@
"partial": "Partially rented",
"none": "Not rented"
},
"subsidyStatus": {
"full": "Subsidized",
"partial": "Partially subsidized"
},
"subsidy": "Subsidy"
},
"assetTable": {
Expand Down
13 changes: 13 additions & 0 deletions src/i18next/locales/fr/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@
"grid": "Carte"
}
},
"assetSubsidy": {
"label": "Loyers subventionnés",
"options": {
"all": "Non filtrés",
"fullySubsidized": "Entièrement subventionnés",
"subsidized": "Subventionnés",
"notSubsidized": "Non subventionnés"
}
},
"assetCard": {
"tokens": "Tokens",
"apr": "Rendement annuel",
Expand All @@ -88,6 +97,10 @@
"partial": "Partiellement louée",
"none": "Non louée"
},
"subsidyStatus": {
"full": "Subventionnée",
"partial": "Partiellement subventionnée"
},
"subsidy": "Loyer subventioné"
},
"assetTable": {
Expand Down
6 changes: 6 additions & 0 deletions src/states/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { atomWithStorage } from 'jotai/utils'

import { AssetSortType, AssetViewType } from 'src/components/assetsView/types'
import { AssetSubsidyType } from 'src/components/assetsView/types'

export const assetViewChoosedAtom = atomWithStorage<AssetViewType>(
'displayChoosed',
AssetViewType.GRID
)

export const assetSubsidyChoosedAtom = atomWithStorage<AssetSubsidyType>(
'subsidyChoosed',
AssetSubsidyType.ALL
)

export const assetSortChoosedAtom = atomWithStorage<AssetSortType>(
'sortChoosed',
AssetSortType.VALUE
Expand Down

0 comments on commit da37267

Please sign in to comment.