1
1
import { useCallback , useEffect , useState , JSX } from 'react' ;
2
- import {
3
- Button ,
4
- Card ,
5
- CardHeader ,
6
- Image ,
7
- Text ,
8
- makeStyles ,
9
- tokens ,
10
- } from '@fluentui/react-components' ;
11
- import { News16Regular } from '@fluentui/react-icons' ;
2
+ import { makeStyles , tokens } from '@fluentui/react-components' ;
12
3
import corpsesDocument from '@microsoftgraveyard/data/corpses.json' ;
13
4
import GraveyardHeader from '@microsoftgraveyard/components/GraveyardHeader' ;
14
5
import GraveyardFooter from '@microsoftgraveyard/components/GraveyardFooter' ;
6
+ import {
7
+ Corpse ,
8
+ CorpseRecord ,
9
+ CorpsesDocument ,
10
+ } from '@microsoftgraveyard/types/corpse' ;
11
+ import Headstone from '@microsoftgraveyard/components/Headstone' ;
15
12
16
13
const useStyles = makeStyles ( {
17
14
main : {
@@ -52,94 +49,6 @@ const useStyles = makeStyles({
52
49
} ,
53
50
} ) ;
54
51
55
- interface Corpse {
56
- name : string ;
57
- qualifier : string | null ;
58
- birthDate : Date | null ;
59
- deathDate : Date ;
60
- description : string ;
61
- link : string ;
62
- }
63
-
64
- interface CorpseRecord {
65
- name : string ;
66
- qualifier : string | null ;
67
- birthDate : string | null ;
68
- deathDate : string ;
69
- description : string ;
70
- link : string ;
71
- }
72
-
73
- interface CorpsesDocument {
74
- $schema : string ;
75
- corpses : CorpseRecord [ ] ;
76
- }
77
-
78
- const getAge = ( start : Date , end : Date ) : { age : number ; period : string } => {
79
- let years = end . getFullYear ( ) - start . getFullYear ( ) ;
80
- if (
81
- end . getMonth ( ) < start . getMonth ( ) ||
82
- ( end . getMonth ( ) === start . getMonth ( ) && end . getDate ( ) < start . getDate ( ) )
83
- ) {
84
- years -- ;
85
- }
86
-
87
- if ( years >= 1 ) {
88
- return { age : years , period : years === 1 ? 'year' : 'years' } ;
89
- }
90
-
91
- const months =
92
- end . getMonth ( ) -
93
- start . getMonth ( ) +
94
- 12 * ( end . getFullYear ( ) - start . getFullYear ( ) ) ;
95
- if ( months >= 1 ) {
96
- return { age : months , period : months === 1 ? 'month' : 'months' } ;
97
- }
98
-
99
- const days = end . getDate ( ) - start . getDate ( ) ;
100
- return { age : days , period : days === 1 ? 'day' : 'days' } ;
101
- } ;
102
-
103
- const getExpectedDeathDate = ( corpse : Corpse ) : string =>
104
- corpse . deathDate . toLocaleDateString ( undefined , {
105
- month : 'long' ,
106
- year : 'numeric' ,
107
- } ) ;
108
-
109
- const getFullName = ( corpse : Corpse ) : string =>
110
- corpse . qualifier ? `${ corpse . name } (${ corpse . qualifier } )` : corpse . name ;
111
-
112
- const getLifeDates = ( corpse : Corpse ) : string =>
113
- corpse . birthDate
114
- ? `${ corpse . birthDate . getFullYear ( ) } - ${ corpse . deathDate . getFullYear ( ) } `
115
- : `${ corpse . deathDate . getFullYear ( ) } ` ;
116
-
117
- const getObituary = ( corpse : Corpse , today : Date ) : string => {
118
- let obituary = '' ;
119
-
120
- const dead = isDead ( corpse , today ) ;
121
- if ( dead ) {
122
- const { age, period } = getAge ( corpse . deathDate , today ) ;
123
- const message = age === 0 ? 'today' : `${ age } ${ period } ago` ;
124
- obituary += `Killed by Microsoft ${ message } , ` ;
125
- } else {
126
- const { age, period } = getAge ( today , corpse . deathDate ) ;
127
- obituary += `To be killed by Microsoft in ${ age } ${ period } , ` ;
128
- }
129
-
130
- obituary += `${ corpse . name } ${ dead ? 'was' : 'is' } ${ corpse . description } .` ;
131
-
132
- if ( dead && corpse . birthDate ) {
133
- const { age, period } = getAge ( corpse . birthDate , corpse . deathDate ) ;
134
- obituary += ` It was ${ age } ${ period } old.` ;
135
- }
136
-
137
- return obituary ;
138
- } ;
139
-
140
- const isDead = ( corpse : Corpse , today : Date ) : boolean =>
141
- corpse . deathDate <= today ;
142
-
143
52
const Graveyard = ( ) => {
144
53
const [ corpses , setCorpses ] = useState < Corpse [ ] > ( [ ] ) ;
145
54
const today : Date = new Date ( ) ;
@@ -168,48 +77,10 @@ const Graveyard = () => {
168
77
) ;
169
78
} , [ ] ) ;
170
79
171
- const renderGraves = ( ) : JSX . Element [ ] => {
80
+ const renderHeadstones = ( ) : JSX . Element [ ] => {
172
81
return corpses . map ( ( corpse , index ) => (
173
82
< li className = { styles . container } key = { index } >
174
- < Card appearance = "filled-alternative" key = { index } >
175
- < CardHeader
176
- image = {
177
- < Image
178
- src = {
179
- isDead ( corpse , today )
180
- ? '/images/headstone.svg'
181
- : '/images/coffin.svg'
182
- }
183
- alt = "a headstone for that which is dead"
184
- height = { 72 }
185
- width = { 72 }
186
- />
187
- }
188
- header = {
189
- < Text as = "h2" weight = "bold" block className = { styles . title } >
190
- { getFullName ( corpse ) }
191
- </ Text >
192
- }
193
- description = {
194
- < Text as = "p" className = { styles . lifeDates } >
195
- { isDead ( corpse , today )
196
- ? getLifeDates ( corpse )
197
- : getExpectedDeathDate ( corpse ) }
198
- </ Text >
199
- }
200
- action = {
201
- < Button
202
- as = "a"
203
- icon = { < News16Regular /> }
204
- appearance = "subtle"
205
- href = { corpse . link }
206
- target = "_blank"
207
- rel = "noreferrer noopener"
208
- />
209
- }
210
- />
211
- < Text as = "p" > { getObituary ( corpse , today ) } </ Text >
212
- </ Card >
83
+ < Headstone corpse = { corpse } today = { today } />
213
84
</ li >
214
85
) ) ;
215
86
} ;
@@ -222,7 +93,7 @@ const Graveyard = () => {
222
93
< main className = { styles . main } >
223
94
< GraveyardHeader />
224
95
< section id = "graveyard" >
225
- < ul className = { styles . list } > { renderGraves ( ) } </ ul >
96
+ < ul className = { styles . list } > { renderHeadstones ( ) } </ ul >
226
97
</ section >
227
98
< GraveyardFooter />
228
99
</ main >
0 commit comments