@@ -3,30 +3,93 @@ import Helmet from 'react-helmet'
3
3
import Link from 'gatsby-link'
4
4
import slugify from 'slugify'
5
5
import GatsbyConfig from '../../../gatsby-config'
6
+ import classNames from "classnames" ;
6
7
7
8
import './changelog.scss'
8
9
10
+ const Section = props => {
11
+ const titleClasses = classNames ( 'sidebar__title' , {
12
+ 'sidebar__title--active' : props . isSectionActive ,
13
+ } )
14
+
15
+ const itemsClasses = classNames ( 'sidebar__items' , {
16
+ 'sidebar__items--active' : props . isSectionActive ,
17
+ } )
18
+
19
+ return (
20
+ < div className = "sidebar__section" >
21
+ < h3 className = { titleClasses } onClick = { props . onSectionTitleClick } >
22
+ { props . title }
23
+ < div className = "sidebar__toggler" >
24
+ { props . isSectionActive ? "+" : "-" }
25
+ </ div >
26
+ </ h3 >
27
+ < ul className = { itemsClasses } >
28
+ { props . items . map ( ( item , index ) => (
29
+ < li className = "sidebar__item" key = { index } >
30
+ < a className = "sidebar__link" href = { `#${ slugify ( item . node . frontmatter . path ) } ` } >
31
+ { item . node . frontmatter . title }
32
+ </ a >
33
+ </ li >
34
+ ) ) }
35
+ </ ul >
36
+ </ div >
37
+ )
38
+ }
39
+
9
40
class IndexRoute extends React . Component {
10
- render ( ) {
41
+ constructor ( props , context ) {
42
+ super ( props , context )
43
+
44
+ this . state = {
45
+ activeSection : new Date ( ) . getFullYear ( ) . toString ( ) ,
46
+ }
47
+ }
48
+
49
+ toggleSection ( year ) {
50
+ return ( event , state ) => {
51
+ event . preventDefault ( )
52
+
53
+ this . setState ( {
54
+ activeSection : this . state . activeSection === year ? null : year ,
55
+ } )
56
+ }
57
+ }
58
+
59
+ groupedByYear ( ) {
11
60
const { edges } = this . props . data . allMarkdownRemark
12
61
62
+ const groupedByYear = { } ;
63
+
64
+ edges . map ( ( item , index ) => {
65
+ const year = item . node . frontmatter . date . substring ( 0 , 4 ) ;
66
+
67
+ if ( groupedByYear [ year ] == undefined ) {
68
+ groupedByYear [ year ] = [ ] ;
69
+ }
70
+
71
+ groupedByYear [ year ] . push ( item ) ;
72
+ } ) ;
73
+
74
+ return groupedByYear ;
75
+ }
76
+
77
+ render ( ) {
13
78
return (
14
79
< div className = "changelog article" >
15
80
< Helmet title = { `Changelog | ${ GatsbyConfig . siteMetadata . title } ` } />
16
81
< div className = "sidebar" >
17
82
< div className = "sidebar__wrapper" >
18
83
< div className = "sidebar__body" >
19
- < ul className = "sidebar__items sidebar__items--active" >
20
- { edges . map ( ( item , index ) => {
21
- return (
22
- < li className = "sidebar__item" >
23
- < a href = { `#${ slugify ( item . node . frontmatter . path ) } ` } >
24
- { item . node . frontmatter . title }
25
- </ a >
26
- </ li >
27
- )
28
- } ) }
29
- </ ul >
84
+ { Object . keys ( this . groupedByYear ( ) ) . reverse ( ) . map ( ( year , index ) => (
85
+ < Section
86
+ key = { index }
87
+ items = { this . groupedByYear ( ) [ year ] }
88
+ title = { year }
89
+ onSectionTitleClick = { this . toggleSection ( year ) }
90
+ isSectionActive = { this . state . activeSection === year }
91
+ />
92
+ ) ) }
30
93
</ div >
31
94
</ div >
32
95
</ div >
@@ -36,9 +99,9 @@ class IndexRoute extends React.Component {
36
99
< p >
37
100
See what's changed or new in HackerOne.
38
101
</ p >
39
- { edges . map ( ( item , index ) => {
102
+ { this . props . data . allMarkdownRemark . edges . map ( ( item , index ) => {
40
103
return (
41
- < div className = "changelog__wrapper" >
104
+ < div className = "changelog__wrapper" key = { index } >
42
105
< div
43
106
className = "changelog__anchor"
44
107
id = { slugify ( item . node . frontmatter . path ) }
0 commit comments