]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/protocol/Item.js
9fcc7e5c6e09b539b837a2056513714dae8af359
[alttp.git] / resources / js / components / protocol / Item.js
1 import moment from 'moment';
2 import PropTypes from 'prop-types';
3 import React from 'react';
4 import { ListGroup } from 'react-bootstrap';
5 import { Trans, withTranslation } from 'react-i18next';
6
7 import Icon from '../common/Icon';
8 import Spoiler from '../common/Spoiler';
9 import { formatTime } from '../../helpers/Result';
10 import { getUserName } from '../../helpers/User';
11 import i18n from '../../i18n';
12
13 const getEntryDate = entry => {
14         const dateStr = moment(entry.created_at).fromNow();
15         return entry.user
16                 ? `${entry.user.username} ${dateStr}`
17                 : dateStr;
18 };
19
20 const getEntryDetailsUsername = entry => {
21         if (!entry || !entry.details || !entry.details.user) return 'Anonymous';
22         return getUserName(entry.details.user);
23 };
24
25 const getEntryRoundNumber = entry =>
26         (entry && entry.details && entry.details.round && entry.details.round.number) || '?';
27
28 const getEntryResultTime = entry => {
29         if (!entry || !entry.details || !entry.details.result) return 'ERROR';
30         const result = entry.details.result;
31         if (result.forfeit) return 'DNF XX';
32         return formatTime(result);
33 };
34
35 const getEntryDescription = entry => {
36         switch (entry.type) {
37                 case 'application.accepted':
38                 case 'application.received':
39                 case 'application.rejected':
40                         return i18n.t(
41                                 `protocol.description.${entry.type}`,
42                                 {
43                                         ...entry,
44                                         username: getEntryDetailsUsername(entry),
45                                 },
46                         );
47                 case 'result.report': {
48                         const time = getEntryResultTime(entry);
49                         return <Trans i18nKey={`protocol.description.${entry.type}`}>
50                                 <Spoiler>{{time}}</Spoiler>,
51                         </Trans>;
52                 }
53                 case 'round.create':
54                 case 'round.lock':
55                 case 'round.unlock':
56                         return i18n.t(
57                                 `protocol.description.${entry.type}`,
58                                 {
59                                         ...entry,
60                                         number: getEntryRoundNumber(entry),
61                                 },
62                         );
63                 case 'result.comment':
64                 case 'tournament.lock':
65                         return i18n.t(
66                                 `protocol.description.${entry.type}`,
67                                 entry,
68                         );
69                 default:
70                         return i18n.t('protocol.description.unknown', entry);
71         }
72 };
73
74 const getEntryIcon = entry => {
75         switch (entry.type) {
76                 case 'result.report':
77                         return <Icon.RESULT />;
78                 case 'round.create':
79                         return <Icon.ADD />;
80                 case 'round.lock':
81                 case 'tournament.lock':
82                         return <Icon.LOCKED />;
83                 case 'round.unlock':
84                         return <Icon.UNLOCKED />;
85                 default:
86                         return <Icon.PROTOCOL />;
87         }
88 };
89
90 const Item = ({ entry }) =>
91         <ListGroup.Item className="d-flex align-items-center">
92                 <div className="pe-3 text-muted">
93                         {getEntryIcon(entry)}
94                 </div>
95                 <div>
96                         <div>
97                                 {getEntryDescription(entry)}
98                         </div>
99                         <div
100                                 className="text-muted"
101                                 title={moment(entry.created_at).format('LLLL')}
102                         >
103                                 {getEntryDate(entry)}
104                         </div>
105                 </div>
106         </ListGroup.Item>;
107
108 Item.propTypes = {
109         entry: PropTypes.shape({
110                 created_at: PropTypes.string,
111         }),
112 };
113
114 Item.defaultProps = {
115         entry: {},
116 };
117
118 export default withTranslation()(Item);