]> git.localhorst.tv Git - alttp.git/commitdiff
result display
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 11 Mar 2022 22:48:45 +0000 (23:48 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 11 Mar 2022 22:48:45 +0000 (23:48 +0100)
app/Models/Result.php
resources/js/components/common/Icon.js
resources/js/components/results/Item.js
resources/js/helpers/Round.js
resources/js/helpers/permissions.js
resources/sass/app.scss
resources/sass/results.scss [new file with mode: 0644]
resources/sass/rounds.scss

index e5c9f7e77f8b756380275ebdf09854fe64df0555..e4954195bb3969ceb3be8510f2e085de276b9dcf 100644 (file)
@@ -17,6 +17,14 @@ class Result extends Model
                return $this->belongsTo(Participant::class);
        }
 
+       public function getHasFinishedAttribute() {
+               return $this->time > 0;
+       }
+
+       protected $appends = [
+               'has_finished',
+       ];
+
        protected $fillable = [
                'round_id',
                'time',
index c9bb3bc37b6a8d5945d3a4d6a76b3a699ba2184b..66d2ac90bf21ed3443751c2193d334ac93a3f068 100644 (file)
@@ -61,7 +61,9 @@ const makePreset = (presetDisplayName, presetName) => {
 
 Icon.DISCORD = makePreset('DiscordIcon', ['fab', 'discord']);
 Icon.EDIT = makePreset('EditIcon', 'edit');
+Icon.FINISHED = makePreset('FinishedIcon', 'square-check');
 Icon.LOGOUT = makePreset('LogoutIcon', 'sign-out-alt');
+Icon.PENDING = makePreset('PendingIcon', 'clock');
 Icon.PROTOCOL = makePreset('ProtocolIcon', 'file-alt');
 
 export default Icon;
index 771c7b62a68ad825a9fe74288db70935c51bdcb5..cc61dd06b66c15169fd0ed8692acb7273e0b75b4 100644 (file)
@@ -2,23 +2,34 @@ import PropTypes from 'prop-types';
 import React from 'react';
 import { withTranslation } from 'react-i18next';
 
+import Icon from '../common/Icon';
 import Box from '../users/Box';
 import { formatTime } from '../../helpers/Result';
 import { findResult } from '../../helpers/Participant';
-import i18n from '../../i18n';
+import { maySeeResults } from '../../helpers/permissions';
+import { withUser } from '../../helpers/UserContext';
 
 const Item = ({
        participant,
        round,
+       tournament,
+       user,
 }) => {
        const result = findResult(participant, round);
        return (
                <div className="result">
                        <Box user={participant.user} />
-                       <div>
-                               {result ?
-                                       <span>{i18n.t('results.time', { time: formatTime(result) })}</span>
-                               : null}
+                       <div className="status">
+                               <span className="time">
+                                       {result && maySeeResults(user, tournament, round) ?
+                                               formatTime(result)
+                                       : null}
+                               </span>
+                               {result && result.has_finished ?
+                                       <Icon.FINISHED size="lg" />
+                               :
+                                       <Icon.PENDING size="lg" />
+                               }
                        </div>
                </div>
        );
@@ -37,4 +48,4 @@ Item.propTypes = {
        }),
 };
 
-export default withTranslation()(Item);
+export default withTranslation()(withUser(Item));
index 8a8b6ade939cc16e16347ab580ecbeec685f6bf0..086517e2f897ec1a79bc709800a0c4b08114b5ad 100644 (file)
@@ -1,3 +1,10 @@
+export const isComplete = (tournament, round) => {
+       if (!tournament || !tournament.participants) return false;
+       if (!round || !round.results) return false;
+       return tournament.participants.length === round.results.length &&
+               round.results.filter(r => !r.has_finished).length === 0;
+};
+
 export const patchResult = (round, result) => {
        if (!round) return round;
        if (!round.results || !round.results.length) {
@@ -13,5 +20,6 @@ export const patchResult = (round, result) => {
 };
 
 export default {
+       isComplete,
        patchResult,
 };
index 891803110ace4d65b34a7acb8d514a9f6676cd6e..2565d44d04edd58f6000c3fc5c60e3326d7cd2f4 100644 (file)
@@ -1,6 +1,8 @@
 /// NOTE: These permissions are for UI cosmetics only!
 /// They should be in sync with the backend Policies.
 
+import Round from './Round';
+
 export const isAdmin = user => user && user.role === 'admin';
 
 export const isSameUser = (user, subject) => user && subject && user.id === subject.id;
@@ -11,9 +13,15 @@ export const isParticipant = (user, tournament) =>
        user && tournament && tournament.participants &&
        tournament.participants.find(p => p.user && p.user.id == user.id);
 
+export const hasFinished = (user, round) =>
+       user && round && round.results &&
+       round.results.find(r => r.user_id == user.id && r.has_finished);
+
 export const mayAddRounds = (user, tournament) =>
        isAdmin(user) || isParticipant(user, tournament);
 
 export const mayViewProtocol = user =>
        isAdmin(user);
 
+export const maySeeResults = (user, tournament, round) =>
+       isAdmin(user) || hasFinished(user, round) || Round.isComplete(tournament, round);
index ff99a53f6534807c665f7f05b9b8e4c4fca293f2..cbb7c679bde7a2574def771e86ce7c4d62af509b 100644 (file)
@@ -13,5 +13,6 @@
 // Custom
 @import 'common';
 @import 'participants';
+@import 'results';
 @import 'rounds';
 @import 'users';
diff --git a/resources/sass/results.scss b/resources/sass/results.scss
new file mode 100644 (file)
index 0000000..c5a7ce6
--- /dev/null
@@ -0,0 +1,24 @@
+.results {
+       .result {
+               padding: 1ex;
+
+               .status {
+                       display: flex;
+                       align-items: center;
+                       justify-content: space-between;
+                       margin-top: 1ex;
+                       padding: 0.5em;
+                       border-radius: 1ex;
+                       background: $dark;
+                       color: $light;
+
+                       .time {
+                               min-width: 9ex;
+                               height: 1.4em;
+                               background: $secondary;
+                               border-radius: 0.5ex;
+                               padding: 0 0.5ex;
+                       }
+               }
+       }
+}
index 8b58071fc8237f48487fd2a1e1cdf1159a6b3f18..83949c925ab50a27d753fbd88b322ffcee577284 100644 (file)
@@ -7,5 +7,9 @@
                border: thin solid $secondary;
                border-radius: 1ex;
                padding: 1ex;
+
+               .info {
+                       padding-right: 1rem;
+               }
        }
 }