]> git.localhorst.tv Git - alttp.git/commitdiff
show placement on scoreboard
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 23 Mar 2022 15:46:54 +0000 (16:46 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 23 Mar 2022 15:46:54 +0000 (16:46 +0100)
resources/js/components/tournament/Scoreboard.js
resources/js/helpers/Tournament.js
resources/js/i18n/de.js
resources/js/i18n/en.js
resources/sass/app.scss
resources/sass/tournaments.scss [new file with mode: 0644]

index e142a80e030488f9a96d474d31d390b9a5259617..ea6a6668727385e2165dcc44ab1d2f853e1940d0 100644 (file)
@@ -6,19 +6,45 @@ import { withTranslation } from 'react-i18next';
 import Icon from '../common/Icon';
 import Box from '../users/Box';
 import { calculateScores } from '../../helpers/Tournament';
+import { withUser } from '../../helpers/UserContext';
 import i18n from '../../i18n';
 
-const Scoreboard = ({ tournament }) =>
-<Table striped className="scoreboard">
+const getRowClassName = (tournament, score, user) => {
+       const classNames = ['score'];
+       if (score && user && score.participant && score.participant.user_id == user.id) {
+               classNames.push('is-self');
+       }
+       return classNames.join(' ');
+};
+
+const getPlacementDisplay = score => {
+       if (score.placement === 1) {
+               return <Icon.FIRST_PLACE className="text-gold" size="lg" />;
+       }
+       if (score.placement === 2) {
+               return <Icon.SECOND_PLACE className="text-silver" size="lg" />;
+       }
+       if (score.placement === 3) {
+               return <Icon.THIRD_PLACE className="text-bronze" size="lg" />;
+       }
+       return score.placement;
+};
+
+const Scoreboard = ({ tournament, user }) =>
+<Table striped className="scoreboard align-middle">
        <thead>
                <tr>
+                       <th>{i18n.t('participants.placementShort')}</th>
                        <th>{i18n.t('participants.participant')}</th>
-                       <th className="text-end">{i18n.t('participants.score')}</th>
+                       <th className="text-end">{i18n.t('participants.scoreShort')}</th>
                </tr>
        </thead>
        <tbody>
        {calculateScores(tournament).map(score =>
-               <tr className="score" key={score.participant.id}>
+               <tr className={getRowClassName(tournament, score, user)} key={score.participant.id}>
+                       <td className="text-center">
+                               {getPlacementDisplay(score)}
+                       </td>
                        <td>
                                <div className="d-flex align-items-center justify-content-between">
                                        <Box user={score.participant.user} />
@@ -35,7 +61,7 @@ const Scoreboard = ({ tournament }) =>
                                        : null}
                                </div>
                        </td>
-                       <td className="text-end text-lg">{score.score}</td>
+                       <td className="text-end">{score.score}</td>
                </tr>
        )}
        </tbody>
@@ -44,6 +70,8 @@ const Scoreboard = ({ tournament }) =>
 Scoreboard.propTypes = {
        tournament: PropTypes.shape({
        }),
+       user: PropTypes.shape({
+       }),
 };
 
-export default withTranslation()(Scoreboard);
+export default withTranslation()(withUser(Scoreboard));
index 38750e7379bd32da27fa3b032506c4fe4bf141d8..7dffebbd07d96c1c189d6f51bdef61b62a524365 100644 (file)
@@ -32,7 +32,21 @@ export const calculateScores = tournament => {
                        }
                }
        });
-       return scores.sort(compareScore).reverse();
+       const sorted = scores.sort(compareScore);
+       let placement = scores.length;
+       let skipped = 0;
+       let lastScore = sorted[0].score;
+       for (let i = 0; i < sorted.length; ++i) {
+               if (sorted[i].score > lastScore) {
+                       placement -= skipped;
+                       skipped = 1;
+                       lastScore = sorted[i].score;
+               } else {
+                       ++skipped;
+               }
+               sorted[i].placement = placement;
+       }
+       return sorted.reverse();
 };
 
 export const compareScore = (a, b) => {
index 79bc2214641be0d19dfd923cba3d75f8910d1d12..9a7bb04c2a13d70e1545c65f432cd16545e5fbd0 100644 (file)
@@ -109,6 +109,8 @@ export default {
                        empty: 'Noch keine Teilnehmer eingetragen',
                        heading: 'Teilnehmer',
                        participant: 'Teilnehmer',
+                       placement: 'Platzierung',
+                       placementShort: '#',
                        roleNames: {
                                admin: 'Administrator',
                                runner: 'Runner',
@@ -116,6 +118,7 @@ export default {
                        roles: 'Teilnahme als',
                        tournament: 'Turnier',
                        score: 'Punktzahl',
+                       scoreShort: 'Punkte',
                },
                protocol: {
                        description: {
index 8cf2806b54aa732a22891a43e76147d8a52a9c30..9f64901a257694f0a2352c3bc4aebf333bbda05e 100644 (file)
@@ -109,6 +109,8 @@ export default {
                        empty: 'No participants on record',
                        heading: 'Participants',
                        participant: 'Participant',
+                       placement: 'Placement',
+                       placementShort: '#',
                        roleNames: {
                                admin: 'Administrator',
                                runner: 'Runner',
@@ -116,6 +118,7 @@ export default {
                        roles: 'Participated as',
                        tournament: 'Tournament',
                        score: 'Score',
+                       scoreShort: 'Score',
                },
                protocol: {
                        description: {
index b19f13e2f5599b494afade01bd3dfffb8b30af46..8cd0fb10448239334162b5fabbd6670c982f8ce3 100644 (file)
@@ -16,4 +16,5 @@
 @import 'participants';
 @import 'results';
 @import 'rounds';
+@import 'tournaments';
 @import 'users';
diff --git a/resources/sass/tournaments.scss b/resources/sass/tournaments.scss
new file mode 100644 (file)
index 0000000..617125f
--- /dev/null
@@ -0,0 +1,7 @@
+.scoreboard {
+       .score {
+               &.is-self {
+                       outline: medium double $secondary;
+               }
+       }
+}