UNPKG

4.27 kBJavaScriptView Raw
1/*eslint-disable react/display-name */
2/*eslint-disable react/no-multi-comp */
3
4import React from 'react';
5import md5 from 'md5-jkmyers';
6import VCard from 'vcf';
7import { Base64 } from 'js-base64';
8
9const initialState = {
10 message: '',
11 error: '',
12 options: {
13 account: '',
14 repo: '',
15 team: '',
16 form: '',
17 branch: '',
18 filterKeys: ['github']
19 },
20 events: {},
21 form: [],
22 links: [],
23 actor: null,
24 user: null,
25 team: null,
26 filterList: null
27};
28
29function vCard(d) {
30 const nameIsAscii = (d.lname + d.fname).match(/[^ -~]/) === null;
31 const card = (new VCard())
32 .set('N', d.lname + ';' + d.fname, nameIsAscii ? {} : {charset: 'UTF-8'})
33 .set('EMAIL', d.email)
34 .set('TEL', d.cell)
35 .toString();
36
37 return 'data:text/vcard;base64,' + Base64.encode(card);
38}
39
40const links = [{
41 key: 'cell',
42 icon: 'mobile',
43 label: 'Cell',
44 url: 'tel:'
45}, {
46 key: 'email',
47 icon: 'mail',
48 label: 'Email',
49 url: 'mailto:'
50}, {
51 key: 'github',
52 icon: 'github',
53 label: 'GitHub',
54 url: 'https://github.com/'
55}, {
56 key: 'twitter',
57 icon: 'twitter',
58 label: 'Twitter',
59 url: 'https://twitter.com/'
60}];
61
62initialState.validators = function(d, c) { return c(null); }; // no-op
63initialState.normalizers = function(d, c) { return c(d); }; // no-op
64
65initialState.sorts = [{
66 key: 'name',
67 sort: function(team) {
68 return team.sort((a, b) => {
69 a = (a.lname) ? a.lname.split(' ') : '';
70 b = (b.lname) ? b.lname.split(' ') : '';
71 a = a[1] ? a[1] : a[0];
72 b = b[1] ? b[1] : b[0];
73 return a.localeCompare(b);
74 });
75 }
76 }, {
77 key: 'date',
78 sort: function(team) {
79 return team.sort((a, b) => {
80 a = new Date(a.birthday).getTime();
81 b = new Date(b.birthday).getTime();
82 return b - a;
83 });
84 }
85}];
86
87initialState.sortKeys = initialState.sorts.reduce((memo, sort) => {
88 memo.push(sort.key);
89 return memo;
90}, []);
91
92initialState.statsTemplate = function(team) {
93 const f = team.filter((_) => {
94 return _.sex === 'xx';
95 }).length;
96
97 const stats = [
98 { name: 'Total team', value: team.length },
99 { name: 'Women', value: (f / team.length * 100).toFixed(1) + '%' },
100 { name: 'Men', value: ((team.length - f) / team.length * 100).toFixed(1) + '%' }
101 ];
102
103 return (
104 <div className='fill-white pad4'>
105 <div className='col12 space-bottom1'>
106 <h2>Team stats</h2>
107 </div>
108 <div className='keyline-all round listing'>
109 {stats.map((stat, i) => {
110 return (
111 <div key={i} className='pad1 col12 clearfix mobile-cols keyline-bottom'>
112 <strong className='col6'>{stat.name}</strong>
113 <span className='col6 text-right'>{stat.value}</span>
114 </div>
115 );
116 })}
117 </div>
118 </div>
119 );
120};
121
122initialState.listingTemplate = function(d) {
123 return (
124 <div>
125 <div className='col12 clearfix space-bottom0'>
126 <img
127 src={`https://www.gravatar.com/avatar/${md5(d.email.toLowerCase())}`}
128 className='square4 dot inline fl' />
129 <div className='info inline pad1x'>
130 <strong className='inline pad1y'>{`${d.fname} ${d.lname}`}</strong>
131 </div>
132 <div className='space pin-topright quiet pad1y'>
133 </div>
134 </div>
135 <div className='col12 clearfix'>
136 <div className='col12 quiet clearfix space-bottom1'>
137 <div className='col6'>
138 <div className='space'>
139 <strong>Birthday</strong>{d.birthday}
140 </div>
141 <div className='space'>
142 <strong>Contact info</strong>
143 <a href={vCard(d)}>Download vCard</a>
144 </div>
145 </div>
146 <div className='col6 mobile-cols clearfix'>
147 {links.map((l, i) => {
148 return (d[l.key]) ? (
149 <div key={i} className='link col6'>
150 <a
151 target='_blank'
152 href={`${l.url}${d[l.key]}`}
153 className={`block col12 truncate strong icon ${l.icon}`}>
154 {`${d[l.key]}`}
155 </a>
156 </div>
157 ) : '';
158 })}
159 </div>
160 </div>
161 </div>
162 </div>
163 );
164};
165
166export default initialState;