Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
carlobeltrame committed Feb 14, 2024
1 parent bff1102 commit 6985f60
Show file tree
Hide file tree
Showing 13 changed files with 431 additions and 1 deletion.
37 changes: 37 additions & 0 deletions app/Http/Controllers/NameGameController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace App\Http\Controllers;

use App\Exceptions\Handler;
use App\Exceptions\MiDataParticipantsListsParsingException;
use App\Exceptions\UnsupportedFormatException;
use App\Http\Requests\ParticipantImportRequest;
use App\Http\Requests\ParticipantRequest;
use App\Models\Course;
use App\Models\Participant;
use App\Util\HtmlString;
use Exception;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\RouteCollectionInterface;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;

class NameGameController extends Controller
{
/**
* Play the name game.
*
* @return Response
*/
public function index()
{
return view('nameGame.index');
}
}
12 changes: 12 additions & 0 deletions lang/de/t.php
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,18 @@
),
"via_midata" => "Via PBS MiData einloggen",
),
"name_game" => array(
"correct" => "Richtig!",
"name_game" => "Name Game",
"next" => "Weiter",
"page_title" => "Name Game",
"participants" => "TN",
"select_all" => "Alle auswählen",
"start" => "Los geht's",
"this_is" => "Das ist:",
"who_is_this" => "Wer ist das?",
"you_guessed" => "Deine Antwort:",
),
"observations" => array(
"add_success" => "Beobachtung erfasst. Mässi!",
"go_to_participant" => "Zu :name",
Expand Down
48 changes: 48 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"yjs": "^13.5.12"
},
"dependencies": {
"@formatjs/intl-durationformat": "^0.2.2",
"jszip": "^3.10.1"
}
}
3 changes: 2 additions & 1 deletion resources/js/components/form/ButtonSubmit.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="form-group row mb-0">
<div :class="inputColumnClass">
<button type="submit" class="btn btn-primary mr-3 mb-1" :disabled="disabled" v-on="$listeners">
<button type="submit" class="btn btn-primary mr-3 mb-1" :disabled="disabled" :value="value" v-on="$listeners">
{{ label }}
</button>

Expand All @@ -15,6 +15,7 @@ export default {
name: 'ButtonSubmit',
props: {
label: { type: String, default: function() { return this.$t('t.global.save') } },
value: { default: null },
disabled: { type: Boolean, default: false },
narrowForm: { type: Boolean, default: false },
},
Expand Down
52 changes: 52 additions & 0 deletions resources/js/components/nameGame/AnswerInput.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<template>
<div v-if="gameMode === 'multipleChoice'">
<button
v-for="option in multipleChoiceOptions"
:key="option.id"
type="submit"
class="btn btn-primary mr-3 mb-1 w-100 h-25"
:value="option.id">
{{ option.scout_name }}
</button>
</div>
<div v-else>{{ participant.scout_name }}</div>
</template>

<script>
export default {
name: 'AnswerInput',
props: {
participant: { type: Object, required: true },
participants: { type: Array, required: true },
gameMode: { type: String, required: true },
},
computed: {
wrongGuess1() {
let result = this.participant
if (this.participants.length < 2) return result
while (result.id === this.participant.id) {
result = this.participants[Math.floor(Math.random() * this.participants.length)]
}
return result
},
wrongGuess2() {
let result = this.participant
if (this.participants.length < 3) return result
while (result.id === this.participant.id || result.id === this.wrongGuess1.id) {
result = this.participants[Math.floor(Math.random() * this.participants.length)]
}
return result
},
multipleChoiceOptions() {
const options = [this.participant, this.wrongGuess1, this.wrongGuess2]
options.sort((a, b) => a.scout_name.localeCompare(b.scout_name))
return options
}
}
}
</script>

<style scoped>
</style>
28 changes: 28 additions & 0 deletions resources/js/components/nameGame/GuessPrompt.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<template>
<row-text v-if="image">
<div class="square-container name-game-image">
<img class="card-img-top img img-responsive full-width" :src="participant.image_path" :alt="$t('t.views.name_game.who_is_this')">
</div>
</row-text>
<div v-else>{{ participant.scout_name }}</div>
</template>

<script>
export default {
name: 'GuessPrompt',
props: {
participant: { type: Object, required: true },
gameMode: { type: String, required: true },
},
computed: {
image() {
return ['multipleChoice', 'manualNameInput'].includes(this.gameMode)
},
}
}
</script>

<style scoped>
</style>
75 changes: 75 additions & 0 deletions resources/js/components/nameGame/NameGame.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<template>
<div class="name-game">
<template v-if="!playing">

<form @submit.prevent="playing = true">

<input-multi-select
:label="$t('t.views.name_game.participants')"
name="selectedParticipants"
v-model="selectedParticipantIds"
multiple
:options="participants"
:display-field="anyDuplicateMembershipGroups ? 'name_and_group' : 'scout_name'"
required
:groups="{[$t('t.views.name_game.select_all')]: participants.map(p => p.id).join()}"
></input-multi-select>

<button-submit :label="$t('t.views.name_game.start')"></button-submit>

</form>

</template>
<template v-else>
<name-game-round
:participants="selectedParticipants"
:game-mode="gameMode"
@finish="playing = false"
></name-game-round>
</template>
</div>
</template>

<script>
import InputMultiSelect from '../form/InputMultiSelect'
import ButtonSubmit from '../form/ButtonSubmit'
import { countBy } from 'lodash'
export default {
name: 'NameGame',
components: { InputMultiSelect, ButtonSubmit },
props: {
participants: { type: Array, required: true },
participantGroups: { type: Array, default: () => [] },
},
data() {
return {
selectedParticipants: this.participants,
playing: false,
gameMode: 'multipleChoice',
}
},
computed: {
selectedParticipantIds: {
get () {
return this.selectedParticipants.map(participant => participant.id).join(',')
},
set (newValue) {
const ids = newValue.split(',')
this.selectedParticipants = this.participants.filter(p => ids.includes(p.id.toString()))
}
},
anyDuplicateMembershipGroups() {
return 1 < Math.max(
...Object.values(countBy(
this.selectedParticipants.filter(participant => !!participant.group), 'group')
)
)
},
}
}
</script>

<style scoped>
</style>
68 changes: 68 additions & 0 deletions resources/js/components/nameGame/NameGameGuess.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<template>
<div>
<guess-prompt :participant="participant" :game-mode="gameMode"></guess-prompt>
<form v-if="guessing" ref="form" @submit.prevent="guess">
<answer-input :participant="participant" :participants="participants" :game-mode="gameMode"></answer-input>
</form>
<form v-else @submit.prevent="next">
<div v-if="correct">
{{ $t('t.views.name_game.correct') }}
</div>
<div v-else>
<div>{{ $t('t.views.name_game.this_is') }}</div>
<div>{{ participant.scout_name }}</div>
<div>{{ $t('t.views.name_game.you_guessed') }}</div>
<div class="d-flex align-items-baseline justify-content-between">
<i class="text-red fas fa-xmark"></i>
&nbsp;
<span>{{ submittedGuess.scout_name }}</span>
</div>
</div>
<button-submit :label="$t('t.views.name_game.next')"></button-submit>
</form>
</div>
</template>

<script>
import ButtonSubmit from '../form/ButtonSubmit.vue'
export default {
name: 'NameGameGuess',
components: { ButtonSubmit },
props: {
participant: { type: Object, required: true },
participants: { type: Array, required: true },
gameMode: { type: String, required: true },
},
data() {
return {
guessing: true,
correct: false,
submittedGuess: null,
}
},
methods: {
guess(event) {
const selectedId = event.submitter.getAttribute('value')
this.submittedGuess = this.participants.find(p => selectedId === `${p.id}`)
if (this.submittedGuess.id === this.participant.id) {
this.correct = true
this.$emit('correct')
} else {
this.correct = false
this.$emit('incorrect')
}
this.guessing = false
},
next() {
this.$emit('advance')
this.guessing = true
}
}
}
</script>

<style scoped>
</style>
Loading

0 comments on commit 6985f60

Please sign in to comment.