fix voting/accepting

This commit is contained in:
Dennis Eichhorn 2023-12-15 01:38:23 +00:00
parent 8d7d1b5354
commit 753cae9186
9 changed files with 182 additions and 32 deletions

View File

@ -51,7 +51,7 @@ return [
],
],
],
'^.*/qa/question.*$' => [
'^.*/qa/question(\?.*|$)$' => [
[
'dest' => '\Modules\QA\Controller\BackendController:viewQADoc',
'verb' => RouteVerb::GET,

View File

@ -361,16 +361,18 @@ final class ApiController extends Controller
->where('isAccepted', true)
->execute();
if ($oldNewAccepted->id !== $oldAccepted->id) {
if ($oldAccepted->id !== 0 &&
$oldNewAccepted->id !== $oldAccepted->id
) {
$oldUnaccepted = clone $oldAccepted;
$oldUnaccepted->isAccepted = !$oldUnaccepted->isAccepted;
$this->updateModel($request->header->account, $oldAccepted, $oldUnaccepted, QAAnswerMapper::class, 'answer', $request->getOrigin());
}
$new = $this->updateAnsweredStatusFromRequest($request);
$newAccepted = $this->updateAnsweredStatusFromRequest($request, $newAccepted);
$this->updateModel($request->header->account, $oldNewAccepted, $newAccepted, QAAnswerMapper::class, 'answer', $request->getOrigin());
$this->createStandardUpdateResponse($request, $response, $new);
$this->createStandardUpdateResponse($request, $response, $newAccepted);
}
/**
@ -401,10 +403,8 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
public function updateAnsweredStatusFromRequest(RequestAbstract $request) : QAAnswer
public function updateAnsweredStatusFromRequest(RequestAbstract $request, QAAnswer $answer) : QAAnswer
{
/** @var \Modules\QA\Models\QAAnswer $answer */
$answer = QAAnswerMapper::get()->where('id', (int) $request->getData('id'))->execute();
$answer->isAccepted = !$answer->isAccepted;
return $answer;

View File

@ -15,8 +15,11 @@ declare(strict_types=1);
namespace Modules\QA\Controller;
use Model\SettingMapper;
use Modules\Admin\Models\AccountMapper;
use Modules\Profile\Models\ProfileMapper;
use Modules\QA\Models\QAAppMapper;
use Modules\QA\Models\QAHelperMapper;
use Modules\QA\Models\QAQuestion;
use Modules\QA\Models\QAQuestionMapper;
use phpOMS\Asset\AssetType;
use phpOMS\Contract\RenderableInterface;
@ -156,8 +159,22 @@ final class BackendController extends Controller
$view->setTemplate('/Modules/QA/Theme/Backend/qa-question-create');
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1006001001, $request, $response);
/** @var \Modules\QA\Models\QAQuestion $question */
$question = QAQuestionMapper::get()->where('id', (int) $request->getData('id'))->execute();
$question = new QAQuestion();
$question->createdBy = ProfileMapper::get()
->with('account')
->with('image')
->where('account', $request->header->account)
->execute();
if ($question->createdBy->account->id === 0) {
$question->createdBy->account = AccountMapper::get()
->where('id', $request->header->account)
->execute();
}
$scores = QAHelperMapper::getAccountScore($question->getAccounts());
$view->data['scores'] = $scores;
$view->data['question'] = $question;
return $view;

View File

@ -14,8 +14,14 @@ declare(strict_types=1);
return ['QA' => [
'All' => 'Alle',
'Answer' => 'Antwort',
'Question' => 'Frage',
'Vote' => 'Bewerten',
'Score' => 'Bewertung',
'Accept' => 'Akzeptieren',
'Badges' => 'Abzeichen',
'List' => 'Liste',
'Title' => 'Titel',
'Name' => 'Name',
'QA' => 'Q&A',
]];

View File

@ -14,8 +14,14 @@ declare(strict_types=1);
return ['QA' => [
'All' => 'All',
'Answer' => 'Answer',
'Question' => 'Question',
'Vote' => 'Vote',
'Score' => 'Score',
'Accept' => 'Accept',
'Badges' => 'Badges',
'List' => 'List',
'Title' => 'Title',
'Name' => 'Name',
'QA' => 'QA',
]];

View File

@ -0,0 +1,78 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\QA
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
use phpOMS\Uri\UriFactory;
/** @var \Modules\QA\Models\QAQuestion $question */
$question = $this->data['question'];
/** @var \Modules\QA\Models\QAAnswer[] $answers */
$answers = $question->getAnswersByScore();
/** @var array $scores */
$scores = $this->data['scores'];
echo $this->data['nav']->render();
?>
<div class="row qa">
<div class="col-xs-12">
<div class="qa-question-view">
<section class="portlet wf-100">
<form id="questionCreate" method="PUT" action="<?= UriFactory::build('{/api}qa/question/create?csrf={$CSRF}'); ?>">
<div class="portlet-head"><?= $this->getHtml('Question'); ?></div>
<div class="portlet-body">
<div class="form-group">
<label for="iTitle"><?= $this->getHtml('Title'); ?></label>
<input id="iTitle" type="text" name="title" value="" />
</div>
<div class="form-group">
<label for="iQuestion"><?= $this->getHtml('Question'); ?></label>
<textarea id="iQuestion" name="plain"></textarea>
</div>
</div>
<div class="portlet-foot qa-portlet-foot">
<div class="tag-list">
<?php
$tags = $question->getTags();
foreach ($tags as $tag) :
if ($tag->id === 0) { continue; }
?>
<span class="tag"><?= empty($tag->icon) ? '' : ''; ?><?= $this->printHtml($tag->getL11n()); ?></span>
<?php endforeach; ?>
</div>
<?php $files = $question->getMedia(); foreach ($files as $file) : ?>
<span><a class="content" href="<?= UriFactory::build('{/base}/media/single?id=' . $file->id);?>"><?= $file->name; ?></a></span>
<?php endforeach; ?>
<input type="submit" name="createButton" id="iCreateButton" value="<?= $this->getHtml('Create', '0', '0'); ?>">
<a class="account-info" href="<?= UriFactory::build('{/base}/profile/single?{?}&id=' . $question->createdBy->id); ?>">
<span class="name">
<div class="content"><?= $this->printHtml($question->createdBy->account->name2); ?> <?= $this->printHtml($question->createdBy->account->name1); ?></div>
<div class="name-score"><?= $this->getHtml('Score') ?>: <?= $scores[$question->createdBy->account->id] ?? 0; ?></div>
</span>
<?php if ($question->createdBy->image->id > 0) : ?>
<img width="40px" alt="<?= $this->getHtml('AccountImage', '0', '0'); ?>" loading="lazy" src="<?= UriFactory::build($question->createdBy->image->getPath()); ?>">
<?php endif; ?>
</a>
</div>
</form>
</section>
</div>
</div>
</div>

View File

@ -32,28 +32,34 @@ echo $this->data['nav']->render();
<div class="score">
<div class="counter-area">
<div class="counter-container">
<?php if ($this->request->header->account !== $question->createdBy->account->id) : ?>
<a id="qa-question-upvote" data-action='[
{
"key": 1, "listener": "click", "action": [
{"key": 1, "type": "event.prevent"},
{"key": 2, "type": "message.request", "uri": "<?= UriFactory::build('{/api}qa/question/vote?id=' . $question->id);?>&type=1", "method": "PUT", "request_type": "json"}
{"key": 2, "type": "message.request", "uri": "<?= UriFactory::build('{/api}qa/question/vote?id=' . $question->id);?>&type=1", "method": "PUT", "request_type": "json"},
{"key": 3, "type": "dom.reload", "delay": 0}
]
}
]' href="#">
<i class="g-icon qa-vote<?= $this->printHtml($question->getAccountVoteScore($this->request->header->account) > 0 ? ' voted' : ' open'); ?>">expand_less</i>
</a>
<?php endif; ?>
<span class="counter"><?= $question->getVoteScore(); ?></span>
<span class="text">Score</span>
<span class="text"><?= $this->getHtml('Score'); ?></span>
<?php if ($this->request->header->account !== $question->createdBy->account->id) : ?>
<a id="qa-question-downvote" data-action='[
{
"key": 1, "listener": "click", "action": [
{"key": 1, "type": "event.prevent"},
{"key": 2, "type": "message.request", "uri": "<?= UriFactory::build('{/api}qa/question/vote?id=' . $question->id);?>&type=-1", "method": "PUT", "request_type": "json"}
{"key": 2, "type": "message.request", "uri": "<?= UriFactory::build('{/api}qa/question/vote?id=' . $question->id);?>&type=-1", "method": "PUT", "request_type": "json"},
{"key": 3, "type": "dom.reload", "delay": 0}
]
}
]' href="#">
<i class="g-icon qa-vote<?= $this->printHtml($question->getAccountVoteScore($this->request->header->account) < 0 ? ' voted' : ' open'); ?>">expand_more</i>
</a>
<?php endif; ?>
</div>
<div class="counter-container">
<span class="counter score<?= $this->printHtml($question->hasAccepted() ? ' done' : ' open'); ?>"><?= $question->getAnswerCount(); ?></span>
@ -64,7 +70,11 @@ echo $this->data['nav']->render();
<section class="portlet wf-100">
<div class="portlet-head"><?= $this->printHtml($question->name); ?></div>
<div class="portlet-body">
<article><?= $question->question; ?></article>
<?php if ($question->id === 0) : ?>
<textarea name="comment"></textarea>
<?php else : ?>
<article><?= $question->question; ?></article>
<?php endif; ?>
</div>
<div class="portlet-foot qa-portlet-foot">
<div class="tag-list">
@ -84,7 +94,7 @@ echo $this->data['nav']->render();
<a class="account-info" href="<?= UriFactory::build('{/base}/profile/single?{?}&id=' . $question->createdBy->id); ?>">
<span class="name">
<div class="content"><?= $this->printHtml($question->createdBy->account->name2); ?> <?= $this->printHtml($question->createdBy->account->name1); ?></div>
<div class="name-score">Score: <?= $scores[$question->createdBy->account->id] ?? 0; ?></div>
<div class="name-score"><?= $this->getHtml('Score') ?>: <?= $scores[$question->createdBy->account->id] ?? 0; ?></div>
</span>
<?php if ($question->createdBy->image->id > 0) : ?>
@ -97,6 +107,27 @@ echo $this->data['nav']->render();
</div>
</div>
<?php if ($question->id !== 0) : ?>
<div class="row qa">
<div class="col-xs-12">
<div class="qa-question-view">
<div class="score"><div class="counter-area"></div></div>
<section class="portlet wf-100">
<form id="answerCreate" class="Comments_create" method="PUT" action="<?= UriFactory::build('{/api}qa/answer/create?question=' . $question->id . '&csrf={$CSRF}'); ?>">
<div class="portlet-head"><?= $this->getHtml('Answer'); ?></div>
<div class="portlet-body">
<textarea name="comment"></textarea>
</div>
<div class="portlet-foot">
<input type="submit" name="createButton" id="iCreateButton" value="<?= $this->getHtml('Create', '0', '0'); ?>">
</div>
</form>
</section>
</div>
</div>
</div>
<?php endif; ?>
<?php foreach ($answers as $answer) : ?>
<div class="row qa">
<div class="col-xs-12">
@ -104,40 +135,51 @@ echo $this->data['nav']->render();
<div class="score">
<div class="counter-area">
<div class="counter-container">
<?php if ($this->request->header->account !== $answer->createdBy->account->id) : ?>
<a id="qa-answer-upvote-<?= $answer->id; ?>" data-action='[
{
"key": 1, "listener": "click", "action": [
{"key": 1, "type": "event.prevent"},
{"key": 2, "type": "message.request", "uri": "<?= UriFactory::build('{/api}qa/answer/vote?id=' . $answer->id);?>&type=1", "method": "PUT", "request_type": "json"}
{"key": 2, "type": "message.request", "uri": "<?= UriFactory::build('{/api}qa/answer/vote?id=' . $answer->id);?>&type=1", "method": "PUT", "request_type": "json"},
{"key": 3, "type": "dom.reload", "delay": 0}
]
}
]' href="#">
<i class="g-icon qa-vote<?= $answer->getAccountVoteScore($this->request->header->account) > 0 ? ' voted' : ' open'; ?>">expand_less</i>
</a>
<?php endif; ?>
<span class="counter"><?= $answer->getVoteScore(); ?></span>
<span class="text">Score</span>
<?php if ($this->request->header->account !== $answer->createdBy->account->id) : ?>
<a id="qa-answer-downvote-<?= $answer->id; ?>" data-action='[
{
"key": 1, "listener": "click", "action": [
{"key": 1, "type": "event.prevent"},
{"key": 2, "type": "message.request", "uri": "<?= UriFactory::build('{/api}qa/answer/vote?id=' . $answer->id);?>&type=-1", "method": "PUT", "request_type": "json"}
{"key": 2, "type": "message.request", "uri": "<?= UriFactory::build('{/api}qa/answer/vote?id=' . $answer->id);?>&type=-1", "method": "PUT", "request_type": "json"},
{"key": 3, "type": "dom.reload", "delay": 0}
]
}
]' href="#">
<i class="g-icon qa-vote<?= $answer->getAccountVoteScore($this->request->header->account) < 0 ? ' voted' : ' open'; ?>">expand_more</i>
</a>
<?php endif; ?>
</div>
<div class="counter-container">
<?php if ($this->request->header->account === $question->createdBy->account->id) : ?>
<a id="qa-answer-accept-<?= $answer->id; ?>" data-action='[
{
"key": 1, "listener": "click", "action": [
{"key": 1, "type": "event.prevent"},
{"key": 2, "type": "message.request", "uri": "<?= UriFactory::build('{/api}qa/answer/accept?id=' . $answer->id);?>&type=1", "method": "PUT", "request_type": "json"}
{"key": 2, "type": "message.request", "uri": "<?= UriFactory::build('{/api}qa/answer/accept?id=' . $answer->id);?>&type=1", "method": "PUT", "request_type": "json"},
{"key": 3, "type": "dom.reload", "delay": 0}
]
}
]' href="#">
<?php endif; ?>
<i class="g-icon qa-accept">check</i>
<?php if ($this->request->header->account === $question->createdBy->account->id) : ?>
</a>
<?php endif; ?>
<span class="text"><?= $this->printHtml($answer->isAccepted ? 'Accepted' : 'Accept'); ?></span>
</div>
</div>

View File

@ -19,13 +19,14 @@
display: flex;
flex-direction: column;
}
.qa-question-view .portlet-body {
height: 100%;
}
.qa textarea {
height: 100px;
}
.qa .qa-accept {
font-size: 2rem;
font-weight: 200;
font-size: 3rem;
font-weight: 800;
color: #ccc;
cursor: pointer; }
.qa .accepted .qa-accept {
@ -33,8 +34,8 @@
.qa .accepted .portlet {
border-top: 3px solid #81e27d; }
.qa .qa-vote {
font-size: 2rem;
font-weight: 200;
font-size: 3rem;
font-weight: 800;
color: #ccc;
cursor: pointer; }
.qa .qa-vote.voted {
@ -57,7 +58,7 @@
.qa .counter-area .text {
font-size: .8rem; }
.qa .score.closed {
background: #f00; }
background: #ee5649; }
.qa .score.open {
background: #f8ffa8; }
.qa .score.done {

View File

@ -30,8 +30,8 @@
flex-direction: column;
}
.portlet-body {
height: 100%;
textarea {
height: 100px;
}
.counter-container+.counter-container {
@ -41,8 +41,8 @@
.qa {
.qa-accept {
font-size: 2rem;
font-weight: 200;
font-size: 3rem;
font-weight: 800;
color: #ccc;
cursor: pointer;
}
@ -58,10 +58,10 @@
}
.qa-vote {
font-size: 2rem;
font-weight: 200;
font-size: 3rem;
color: #ccc;
cursor: pointer;
font-weight: 800;
&.voted {
color: #81e27d;
@ -95,7 +95,7 @@
.score {
&.closed {
background: #f00;
background: #ee5649;
}
&.open {