return $this->belongsTo(User::class);
}
+ protected $casts = [
+ 'roles' => 'array',
+ ];
+
protected $with = [
'user',
];
public function isParticipant(Tournament $tournament) {
foreach ($tournament->participants as $participant) {
- if ($participant->user->id == $this->id) {
+ if ($participant->user_id == $this->id) {
return true;
}
}
return false;
}
+ public function isRunner(Tournament $tournament) {
+ foreach ($tournament->participants as $participant) {
+ if ($participant->user_id == $this->id) {
+ return in_array('runner', $participant->roles);
+ }
+ }
+ return false;
+ }
+
+ public function isTournamentAdmin(Tournament $tournament) {
+ foreach ($tournament->participants as $participant) {
+ if ($participant->user_id == $this->id) {
+ return in_array('admin', $participant->roles);
+ }
+ }
+ return false;
+ }
+
public function participation() {
return $this->hasMany(Participant::class);
}
*/
public function viewProtocol(User $user, Tournament $tournament)
{
- return $user->role === 'admin';
+ return $user->role === 'admin' || $user->isTournamentAdmin($tournament);
}
}
--- /dev/null
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+ /**
+ * Run the migrations.
+ *
+ * @return void
+ */
+ public function up()
+ {
+ Schema::table('participants', function(Blueprint $table) {
+ $table->text('roles')->default('["runner"]');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('participants', function(Blueprint $table) {
+ $table->dropColumn('roles');
+ });
+ }
+};
import Item from './Item';
import { sortByResult } from '../../helpers/Participant';
+import { getRunners } from '../../helpers/Tournament';
const List = ({ round, tournament }) => <div className="results d-flex flex-wrap">
- {sortByResult(tournament.participants, round).map((participant, index) =>
+ {sortByResult(getRunners(tournament), round).map((participant, index) =>
<Item
index={index}
key={participant.id}
import Scoreboard from './Scoreboard';
import Protocol from '../protocol/Protocol';
import Rounds from '../rounds/List';
+import Box from '../users/Box';
import {
mayAddRounds,
mayViewProtocol,
} from '../../helpers/permissions';
+import {
+ getRunners,
+ getTournamentAdmins,
+ hasRunners,
+ hasTournamentAdmins,
+} from '../../helpers/Tournament';
import { withUser } from '../../helpers/UserContext';
import i18n from '../../i18n';
<div className="d-flex align-items-center justify-content-between">
<h2>{i18n.t('tournaments.scoreboard')}</h2>
</div>
- {tournament.participants ?
+ {hasRunners(tournament) ?
<Scoreboard tournament={tournament} />
: null}
+ {hasTournamentAdmins(tournament) ?
+ <>
+ <div className="d-flex align-items-center justify-content-between">
+ <h2>{i18n.t('tournaments.admins')}</h2>
+ </div>
+ {getTournamentAdmins(tournament).map(p =>
+ <p key={p.id}><Box user={p.user} /></p>
+ )}
+ </>
+ : null}
</Col>
</Row>
</Container>;
return round.results.find(result => result.user_id === participant.user_id);
};
+export const isRunner = participant =>
+ participant && participant.roles && participant.roles.includes('runner');
+
+export const isTournamentAdmin = participant =>
+ participant && participant.roles && participant.roles.includes('admin');
+
export const patchUser = (participant, user) => {
if (!participant || !user) return participant;
if (participant.user_id != user.id) return participant;
compareResult,
compareUsername,
findResult,
+ isRunner,
+ isTournamentAdmin,
patchUser,
sortByResult,
};
import Round from './Round';
export const calculateScores = tournament => {
- if (!tournament || !tournament.participants || !tournament.participants.length) return [];
- const scores = tournament.participants.map(participant => ({ participant, score: 0 }));
+ const scores = getRunners(tournament).map(participant => ({ participant, score: 0 }));
if (!tournament.rounds || !tournament.rounds.length) return scores;
tournament.rounds.forEach(round => {
const filtered = Participant
const b_score = b && b.score ? b.score : 0;
if (a_score < b_score) return -1;
if (b_score < a_score) return 1;
- return 0;
+ return Participant.compareUsername(a.participant, b.participant);
};
export const findParticipant = (tournament, user) => {
return tournament.participants.find(p => p.user_id == user.id);
};
+export const getRunners = tournament => {
+ if (!tournament || !tournament.participants || !tournament.participants.length) return [];
+ return tournament.participants
+ .filter(Participant.isRunner)
+ .sort(Participant.compareUsername);
+};
+
+export const getTournamentAdmins = tournament => {
+ if (!tournament || !tournament.participants || !tournament.participants.length) return [];
+ return tournament.participants
+ .filter(Participant.isTournamentAdmin)
+ .sort(Participant.compareUsername);
+};
+
+export const hasRunners = tournament => {
+ return getRunners(tournament).length > 0;
+};
+
+export const hasTournamentAdmins = tournament => {
+ return getTournamentAdmins(tournament).length > 0;
+};
+
export const patchResult = (tournament, result) => {
if (!tournament || !tournament.rounds) return tournament;
return {
user && tournament && tournament.participants &&
tournament.participants.find(p => p.user && p.user.id == user.id);
+export const isRunner = (user, tournament) => {
+ const p = isParticipant(user, tournament);
+ return p && p.roles && p.roles.includes('runner');
+};
+
+export const isTournamentAdmin = (user, tournament) => {
+ const p = isParticipant(user, tournament);
+ return p && p.roles && p.roles.includes('admin');
+};
+
export const hasFinished = (user, round) =>
user && round && round.results &&
round.results.find(r => r.user_id == user.id && r.has_finished);
export const maySetSeed = (user, tournament) =>
isAdmin(user) || isParticipant(user, tournament);
-export const mayViewProtocol = user =>
- isAdmin(user);
+export const mayViewProtocol = (user, tournament) =>
+ isAdmin(user) || isTournamentAdmin(user, tournament);
export const maySeeResults = (user, tournament, round) =>
isAdmin(user) || hasFinished(user, round) || Round.isComplete(tournament, round);
setSeedSuccess: 'Seed eingetragen',
},
tournaments: {
+ admins: 'Organisation',
scoreboard: 'Scoreboard',
},
users: {
setSeedSuccess: 'Seed set',
},
tournaments: {
+ admins: 'Admins',
scoreboard: 'Scoreboard',
},
users: {