diff --git a/README.md b/README.md
index 854e593..835cf28 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,7 @@ Szkielet komponentu Joomla 6 do gromadzenia pytań testowych.
- filtrowanie listy pytań po kategorii,
- przełącznik widoku listy: same pytania albo pytania z odpowiedziami,
- frontendowy widok pytań filtrowany po symbolu arkusza egzaminacyjnego,
+- frontendowy widok testu na podstawie wybranego zestawu pytań,
- pozycję menu „Arkusz egzaminacyjny” z opcjonalnym symbolem arkusza,
- listę wyboru dostępnych symboli arkuszy na stronie klienckiej,
- możliwość rozwiązania arkusza i wyświetlenia wyniku oraz odpowiedzi poprawnych i zaznaczonych,
@@ -24,6 +25,6 @@ Szkielet komponentu Joomla 6 do gromadzenia pytań testowych.
## Instalacja
-W Joomla wybierz **System → Install → Install from Folder** i wskaż ten katalog. Manifestem instalacyjnym jest `com_testquestions.xml` (wersja 1.13.5).
+W Joomla wybierz **System → Install → Install from Folder** i wskaż ten katalog. Manifestem instalacyjnym jest `com_testquestions.xml` (wersja 1.14.0).
Po instalacji komponent jest dostępny w panelu administratora jako **Pytania testowe**.
diff --git a/administrator/components/com_testquestions/sql/updates/mysql/1.14.0.sql b/administrator/components/com_testquestions/sql/updates/mysql/1.14.0.sql
new file mode 100644
index 0000000..897d15c
--- /dev/null
+++ b/administrator/components/com_testquestions/sql/updates/mysql/1.14.0.sql
@@ -0,0 +1 @@
+-- No database changes required for version 1.14.0.
diff --git a/com_testquestions.xml b/com_testquestions.xml
index 6b1930d..036f9a4 100644
--- a/com_testquestions.xml
+++ b/com_testquestions.xml
@@ -4,7 +4,7 @@
2026-10-14
Komponent
GNU General Public License version 2 or later
- 1.13.5
+ 1.14.0
COM_TESTQUESTIONS_DESCRIPTION
com_testquestions
Komponent\Component\Testquestions
diff --git a/components/com_testquestions/language/en-GB/com_testquestions.ini b/components/com_testquestions/language/en-GB/com_testquestions.ini
index 5e582de..7edce07 100644
--- a/components/com_testquestions/language/en-GB/com_testquestions.ini
+++ b/components/com_testquestions/language/en-GB/com_testquestions.ini
@@ -17,3 +17,5 @@ COM_TESTQUESTIONS_MENU_ITEM_TITLE="Arkusz egzaminacyjny"
COM_TESTQUESTIONS_MENU_ITEM_DESCRIPTION="Wyświetla pytania z wybranego arkusza egzaminacyjnego."
COM_TESTQUESTIONS_MENU_TEST_SYMBOL_DESC="Opcjonalnie wybierz symbol arkusza, który ma być wyświetlany po wejściu z menu."
COM_TESTQUESTIONS_ENTER_ANSWER="Wpisz odpowiedź"
+COM_TESTQUESTIONS_SET_DURATION="Czas trwania testu"
+COM_TESTQUESTIONS_SET_NOT_FOUND="Nie znaleziono wybranego zestawu testowego."
diff --git a/components/com_testquestions/language/en-GB/com_testquestions.sys.ini b/components/com_testquestions/language/en-GB/com_testquestions.sys.ini
index 89e8afb..e8996cf 100644
--- a/components/com_testquestions/language/en-GB/com_testquestions.sys.ini
+++ b/components/com_testquestions/language/en-GB/com_testquestions.sys.ini
@@ -1,3 +1,6 @@
COM_TESTQUESTIONS="Pytania testowe"
COM_TESTQUESTIONS_MENU_ITEM_TITLE="Arkusz egzaminacyjny"
COM_TESTQUESTIONS_MENU_ITEM_DESCRIPTION="Wyświetla pytania z wybranego arkusza egzaminacyjnego."
+COM_TESTQUESTIONS_SET_MENU_ITEM_TITLE="Zestaw testowy"
+COM_TESTQUESTIONS_SET_MENU_ITEM_DESCRIPTION="Wyświetla test na podstawie wybranego zestawu pytań."
+COM_TESTQUESTIONS_SET_SELECT="Zestaw pytań"
diff --git a/components/com_testquestions/src/Model/SetModel.php b/components/com_testquestions/src/Model/SetModel.php
new file mode 100644
index 0000000..8d549ab
--- /dev/null
+++ b/components/com_testquestions/src/Model/SetModel.php
@@ -0,0 +1,59 @@
+getMenu()->getActive();
+ $menuSetId = $menu ? (int) $menu->getParams()->get('set_id', 0) : 0;
+
+ return $application->getInput()->getInt('set_id', $menuSetId);
+ }
+
+ public function getSet()
+ {
+ $db = Factory::getContainer()->get('DatabaseDriver');
+ $setId = $this->getSetId();
+
+ if ($setId < 1) {
+ return null;
+ }
+
+ return $db->setQuery(
+ $db->getQuery(true)
+ ->select(['s.*', 'sub.title AS subject_title'])
+ ->from($db->quoteName('#__testquestions_sets', 's'))
+ ->leftJoin($db->quoteName('#__testquestions_subjects', 'sub') . ' ON sub.id = s.subject_id')
+ ->where('s.id = ' . $setId)
+ ->where('s.published = 1')
+ )->loadObject();
+ }
+
+ public function getItems()
+ {
+ $db = Factory::getContainer()->get('DatabaseDriver');
+ $setId = $this->getSetId();
+
+ if ($setId < 1) {
+ return [];
+ }
+
+ return $db->setQuery(
+ $db->getQuery(true)
+ ->select(['q.id', 'q.question_type', 'q.question', 'q.answer_a', 'q.answer_b', 'q.answer_c', 'q.answer_d', 'q.answer_open', 'q.correct_answer', 'q.image'])
+ ->from($db->quoteName('#__testquestions_set_questions', 'sq'))
+ ->innerJoin($db->quoteName('#__testquestions_questions', 'q') . ' ON q.id = sq.question_id')
+ ->where('sq.set_id = ' . $setId)
+ ->where('q.published = 1')
+ ->order('sq.ordering ASC, q.id ASC')
+ )->loadObjectList();
+ }
+}
diff --git a/components/com_testquestions/src/View/Set/HtmlView.php b/components/com_testquestions/src/View/Set/HtmlView.php
new file mode 100644
index 0000000..8061646
--- /dev/null
+++ b/components/com_testquestions/src/View/Set/HtmlView.php
@@ -0,0 +1,67 @@
+set = $this->get('Set');
+ $this->items = $this->get('Items');
+ $this->results = $this->buildResults($this->items);
+
+ return parent::display($tpl);
+ }
+
+ protected function buildResults(array $items)
+ {
+ $input = Factory::getApplication()->getInput();
+
+ if ($input->getCmd('task') !== 'check' || $input->getMethod() !== 'POST') {
+ return null;
+ }
+
+ $answers = (array) $input->post->get('answers', [], 'array');
+ $results = [];
+ $correct = 0;
+
+ foreach ($items as $item) {
+ $selected = isset($answers[$item->id]) ? trim((string) $answers[$item->id]) : '';
+ $isCorrect = false;
+
+ if ($item->question_type === 'open') {
+ $patterns = preg_split('/\s*\|\s*/', (string) $item->answer_open, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($patterns as $pattern) {
+ if (mb_strtolower(trim($pattern), 'UTF-8') === mb_strtolower($selected, 'UTF-8')) {
+ $isCorrect = true;
+ break;
+ }
+ }
+ } else {
+ $isCorrect = (string) $item->correct_answer === $selected;
+ }
+
+ if ($isCorrect) {
+ $correct++;
+ }
+
+ $results[$item->id] = ['selected' => $selected, 'correct' => $isCorrect];
+ }
+
+ return [
+ 'items' => $results,
+ 'correct' => $correct,
+ 'total' => count($items),
+ 'percentage' => count($items) ? round(($correct / count($items)) * 100, 2) : 0,
+ ];
+ }
+}
diff --git a/components/com_testquestions/tmpl/set/default.php b/components/com_testquestions/tmpl/set/default.php
new file mode 100644
index 0000000..ecfb635
--- /dev/null
+++ b/components/com_testquestions/tmpl/set/default.php
@@ -0,0 +1,56 @@
+
+
diff --git a/components/com_testquestions/tmpl/set/default.xml b/components/com_testquestions/tmpl/set/default.xml
new file mode 100644
index 0000000..a0ae1a2
--- /dev/null
+++ b/components/com_testquestions/tmpl/set/default.xml
@@ -0,0 +1,13 @@
+
+
+
+ COM_TESTQUESTIONS_SET_MENU_ITEM_DESCRIPTION
+
+
+
+
+