better ux with search functionality

This commit is contained in:
2026-05-28 10:58:31 +02:00
parent 8915c8d182
commit b049a9ab9f
10 changed files with 997 additions and 252 deletions

View File

@ -6,6 +6,16 @@
const QDB_DEV_GLASS_LABELS = ['never_glass', 'little_glass', 'moderate_glass', 'much_glass', 'extreme_glass'];
const QDB_DEV_GLASS_POINTS = [
'never_glass' => 0,
'little_glass' => 1,
'moderate_glass' => 2,
'much_glass' => 3,
'extreme_glass' => 4,
];
require_once __DIR__ . '/app_answers.php';
/**
* @return array{imported: array, skipped: array, errors: string[]}
*/
@ -338,11 +348,20 @@ function qdb_dev_build_answers_for_questionnaire(PDO $pdo, string $qnID, int $va
case 'multi_check_box_question':
$opts = $optionsByQuestion[$q['questionID']] ?? [];
if ($opts) {
$count = min(2, count($opts));
for ($i = 0; $i < $count; $i++) {
$pickCount = min(5, max(2, count($opts) > 20 ? 4 : 2), count($opts));
$keys = [];
for ($i = 0; $i < $pickCount; $i++) {
$pick = $opts[($v + $i) % count($opts)];
$key = qdb_option_key($pick) ?: $pick['defaultText'];
$answers[] = ['questionID' => $localId, 'answerOptionKey' => $key];
if ($key !== '') {
$keys[] = $key;
}
}
if ($keys !== []) {
$answers[] = [
'questionID' => $localId,
'freeTextValue' => qdb_encode_multi_check_values($keys),
];
}
}
break;
@ -376,9 +395,15 @@ function qdb_dev_build_answers_for_questionnaire(PDO $pdo, string $qnID, int $va
$year = 2018 + ($v % 6);
$month = 1 + ($v % 12);
$day = 1 + ($v % 28);
$precision = $config['precision'] ?? 'full';
$dateValue = match ($precision) {
'year' => sprintf('%04d', $year),
'year_month' => sprintf('%04d-%02d', $year, $month),
default => sprintf('%04d-%02d-%02d', $year, $month, $day),
};
$answers[] = [
'questionID' => $localId,
'freeTextValue' => sprintf('%04d-%02d-%02d', $year, $month, $day),
'freeTextValue' => $dateValue,
];
break;
@ -419,11 +444,13 @@ function qdb_dev_persist_submission(
$qRows = $pdo->prepare('SELECT questionID, type, configJson FROM question WHERE questionnaireID = :qn');
$qRows->execute([':qn' => $qnID]);
$shortIdMap = [];
$typeByFullId = [];
$freeTextMaxLen = [];
foreach ($qRows->fetchAll(PDO::FETCH_ASSOC) as $qRow) {
$fullId = $qRow['questionID'];
$parts = explode('__', $fullId);
$shortIdMap[end($parts)] = $fullId;
$typeByFullId[$fullId] = $qRow['type'] ?? '';
if (($qRow['type'] ?? '') === 'free_text') {
$cfg = json_decode($qRow['configJson'] ?? '{}', true) ?: [];
$freeTextMaxLen[$fullId] = max(1, min((int)($cfg['maxLength'] ?? 500), 10000));
@ -480,11 +507,31 @@ function qdb_dev_persist_submission(
}
$answerOptionID = null;
$optionKey = $a['answerOptionKey'] ?? null;
if ($optionKey !== null && isset($optionMap[$fullQID][(string)$optionKey])) {
$opt = $optionMap[$fullQID][(string)$optionKey];
$answerOptionID = $opt['answerOptionID'];
$sumPoints += $opt['points'];
$qType = $typeByFullId[$fullQID] ?? '';
if ($qType === 'glass_scale_question' && $freeTextValue !== null && $freeTextValue !== '') {
$decoded = json_decode($freeTextValue, true);
if (is_array($decoded)) {
foreach ($decoded as $label) {
$label = trim((string)$label);
if ($label !== '') {
$sumPoints += QDB_DEV_GLASS_POINTS[$label] ?? 0;
}
}
}
} elseif ($qType === 'multi_check_box_question' && $freeTextValue !== null && $freeTextValue !== '') {
foreach (qdb_decode_multi_check_values($freeTextValue) as $mk) {
if (isset($optionMap[$fullQID][$mk])) {
$sumPoints += $optionMap[$fullQID][$mk]['points'];
}
}
} else {
$optionKey = $a['answerOptionKey'] ?? null;
if ($optionKey !== null && isset($optionMap[$fullQID][(string)$optionKey])) {
$opt = $optionMap[$fullQID][(string)$optionKey];
$answerOptionID = $opt['answerOptionID'];
$sumPoints += $opt['points'];
}
}
$answerInsert->execute([