@@ -5,13 +5,13 @@ import { useTranslations } from 'next-intl'
5
5
import { FC , PropsWithChildren } from 'react'
6
6
import { MarkdownContent } from '~/components/generic/markdown-content'
7
7
import { IntlMessageKeys } from '~/helpers/types'
8
- import { pick } from '~/helpers/utilities'
9
8
import { Features } from '~/server/db/constants/features'
10
9
import {
11
10
featureDisplayGroups ,
12
11
getCompositeFeatureKey ,
12
+ getCompositeFeatureValues ,
13
13
getIconForFeature ,
14
- getMoreInfoContent ,
14
+ useFeatureDisplay ,
15
15
} from '~/server/db/constants/features-display-data'
16
16
17
17
export const FeaturesBlock : FC < { features : Features ; className ?: string } > = ( {
@@ -20,118 +20,124 @@ export const FeaturesBlock: FC<{ features: Features; className?: string }> = ({
20
20
} ) => {
21
21
const t = useTranslations ( 'data.features' )
22
22
23
+ const { allValuesNull, allValuesNullInGroup, getMoreInfoContent } =
24
+ useFeatureDisplay ( features )
25
+
26
+ if ( allValuesNull ) return null
27
+
23
28
return (
24
29
< Card className = { className } radius = "lg" shadow = "sm" >
25
30
< CardBody className = "gap-2" >
26
- { featureDisplayGroups . map ( ( group ) => (
27
- < FeatureList key = { group . key } title = { t ( `titles.${ group . key } ` ) } >
28
- { group . featureDisplays . map ( ( featureDisplay ) => {
29
- if ( 'hidden' in featureDisplay && featureDisplay . hidden ) {
30
- return null
31
- }
32
-
33
- switch ( featureDisplay . type ) {
34
- case 'number' :
35
- case 'text' : {
36
- const value = features [ featureDisplay . key ]
37
- if ( value === null || value === undefined ) return null
38
-
39
- if ( 'showRaw' in featureDisplay && featureDisplay . showRaw ) {
40
- return (
41
- < FeatureItem
42
- key = { featureDisplay . key }
43
- icon = { featureDisplay . icon }
44
- text = { String ( value ) }
45
- moreInfo = { getMoreInfoContent ( featureDisplay , features ) }
46
- />
47
- )
48
- } else {
49
- return (
50
- < FeatureItem
51
- key = { featureDisplay . key }
52
- icon = { featureDisplay . icon }
53
- text = { t (
54
- `values.${ `${ featureDisplay . type } .${ featureDisplay . key } ` as IntlMessageKeys < 'data.features.values' > } ` ,
55
- {
56
- value,
57
- }
58
- ) }
59
- moreInfo = { getMoreInfoContent ( featureDisplay , features ) }
60
- />
61
- )
62
- }
63
- }
64
- case 'markdown' : {
65
- const value = features [ featureDisplay . key ]
66
- if ( value === null || value === undefined ) return null
67
- return (
68
- < MarkdownFeatureItem
69
- key = { featureDisplay . key }
70
- icon = { featureDisplay . icon }
71
- label = { t ( `labels.${ featureDisplay . key } ` ) }
72
- content = { value }
73
- />
74
- )
75
- }
76
- case 'enum' : {
77
- const value = features [ featureDisplay . key ]
78
- if ( value === null || value === undefined ) return null
79
-
80
- return (
81
- < FeatureItem
82
- key = { featureDisplay . key }
83
- icon = { getIconForFeature ( featureDisplay , value ) }
84
- text = { t (
85
- `values.enum.${ `${ featureDisplay . key } .${ value } ` as IntlMessageKeys < 'data.features.values.enum' > } `
86
- ) }
87
- moreInfo = { getMoreInfoContent ( featureDisplay , features ) }
88
- />
89
- )
90
- }
91
- case 'boolean' : {
92
- const value = features [ featureDisplay . key ]
93
- if ( value === null || value === undefined ) return null
94
-
95
- return (
96
- < BooleanFeatureItem
97
- key = { featureDisplay . key }
98
- icon = { getIconForFeature ( featureDisplay , true ) }
99
- iconOff = { getIconForFeature ( featureDisplay , false ) }
100
- text = { t ( `values.boolean.${ featureDisplay . key } .${ value } ` ) }
101
- value = { value }
102
- moreInfo = { getMoreInfoContent ( featureDisplay , features ) }
103
- />
104
- )
105
- }
106
- case 'composite' : {
107
- const rawValues = pick (
108
- features ,
109
- featureDisplay . keys
110
- ) as Parameters < ( typeof featureDisplay ) [ 'transformValues' ] > [ 0 ]
111
-
112
- if (
113
- featureDisplay . showIf &&
114
- ! featureDisplay . showIf ( rawValues )
115
- ) {
31
+ { featureDisplayGroups . map (
32
+ ( group ) =>
33
+ ! allValuesNullInGroup [ group . key ] && (
34
+ < FeatureList key = { group . key } title = { t ( `titles.${ group . key } ` ) } >
35
+ { group . featureDisplays . map ( ( featureDisplay ) => {
36
+ if ( 'hidden' in featureDisplay && featureDisplay . hidden ) {
116
37
return null
117
38
}
118
39
119
- const values = featureDisplay ?. transformValues ( rawValues )
120
-
121
- const key = getCompositeFeatureKey ( featureDisplay . keys )
122
- return (
123
- < FeatureItem
124
- key = { key }
125
- icon = { featureDisplay . icon }
126
- text = { t ( `values.composite.${ key } ` , values ) }
127
- moreInfo = { getMoreInfoContent ( featureDisplay , features ) }
128
- />
129
- )
130
- }
131
- }
132
- } ) }
133
- </ FeatureList >
134
- ) ) }
40
+ switch ( featureDisplay . type ) {
41
+ case 'number' :
42
+ case 'text' : {
43
+ const value = features [ featureDisplay . key ]
44
+ if ( value === null || value === undefined ) return null
45
+
46
+ if (
47
+ 'showRaw' in featureDisplay &&
48
+ featureDisplay . showRaw
49
+ ) {
50
+ return (
51
+ < FeatureItem
52
+ key = { featureDisplay . key }
53
+ icon = { featureDisplay . icon }
54
+ text = { String ( value ) }
55
+ moreInfo = { getMoreInfoContent ( featureDisplay ) }
56
+ />
57
+ )
58
+ } else {
59
+ return (
60
+ < FeatureItem
61
+ key = { featureDisplay . key }
62
+ icon = { featureDisplay . icon }
63
+ text = { t (
64
+ `values.${ `${ featureDisplay . type } .${ featureDisplay . key } ` as IntlMessageKeys < 'data.features.values' > } ` ,
65
+ {
66
+ value,
67
+ }
68
+ ) }
69
+ moreInfo = { getMoreInfoContent ( featureDisplay ) }
70
+ />
71
+ )
72
+ }
73
+ }
74
+ case 'markdown' : {
75
+ const value = features [ featureDisplay . key ]
76
+ if ( value === null || value === undefined ) return null
77
+ return (
78
+ < MarkdownFeatureItem
79
+ key = { featureDisplay . key }
80
+ icon = { featureDisplay . icon }
81
+ label = { t ( `labels.${ featureDisplay . key } ` ) }
82
+ content = { value }
83
+ />
84
+ )
85
+ }
86
+ case 'enum' : {
87
+ const value = features [ featureDisplay . key ]
88
+ if ( value === null || value === undefined ) return null
89
+
90
+ return (
91
+ < FeatureItem
92
+ key = { featureDisplay . key }
93
+ icon = { getIconForFeature ( featureDisplay , value ) }
94
+ text = { t (
95
+ `values.enum.${ `${ featureDisplay . key } .${ value } ` as IntlMessageKeys < 'data.features.values.enum' > } `
96
+ ) }
97
+ moreInfo = { getMoreInfoContent ( featureDisplay ) }
98
+ />
99
+ )
100
+ }
101
+ case 'boolean' : {
102
+ const value = features [ featureDisplay . key ]
103
+ if ( value === null || value === undefined ) return null
104
+
105
+ return (
106
+ < BooleanFeatureItem
107
+ key = { featureDisplay . key }
108
+ icon = { getIconForFeature ( featureDisplay , true ) }
109
+ iconOff = { getIconForFeature ( featureDisplay , false ) }
110
+ text = { t (
111
+ `values.boolean.${ featureDisplay . key } .${ value } `
112
+ ) }
113
+ value = { value }
114
+ moreInfo = { getMoreInfoContent ( featureDisplay ) }
115
+ />
116
+ )
117
+ }
118
+ case 'composite' : {
119
+ const values = getCompositeFeatureValues (
120
+ featureDisplay ,
121
+ features
122
+ )
123
+
124
+ if ( ! values ) return null
125
+
126
+ const key = getCompositeFeatureKey ( featureDisplay . keys )
127
+ return (
128
+ < FeatureItem
129
+ key = { key }
130
+ icon = { featureDisplay . icon }
131
+ text = { t ( `values.composite.${ key } ` , values ) }
132
+ moreInfo = { getMoreInfoContent ( featureDisplay ) }
133
+ />
134
+ )
135
+ }
136
+ }
137
+ } ) }
138
+ </ FeatureList >
139
+ )
140
+ ) }
135
141
</ CardBody >
136
142
</ Card >
137
143
)
0 commit comments