diff --git a/admin.php b/admin.php index fbf5a7e..ecb138a 100644 --- a/admin.php +++ b/admin.php @@ -33,47 +33,57 @@ require_once 'templates/header.php';
-
-

Feedback Submissions

-
- Dashboard - Manage Surveys - Export to CSV - Logout +
+
+
+

Feedback Submissions

+ +
-
- -
- - - - - - - - - - - - - - - - - +
+
+
SurveySubmitterEmailSubmitted AtAnswers
No feedback submissions yet.
+ - - - - - + + + + + - - - -
- View Answers - SurveySubmitterEmailSubmitted AtAnswers
+ + + + + No feedback submissions yet. + + + + + + + + + + View Answers + + + + + + +
+
diff --git a/api.php b/api.php index 6fdecd6..01a890a 100644 --- a/api.php +++ b/api.php @@ -21,36 +21,61 @@ switch ($action) { break; case 'survey_question_analytics': - $surveys_stmt = db()->query("SELECT * FROM surveys"); - $surveys = $surveys_stmt->fetchAll(PDO::FETCH_ASSOC); + $surveys_stmt = db()->query("SELECT id, title FROM surveys"); + $surveys = $surveys_stmt->fetchAll(PDO::FETCH_KEY_PAIR); + + $questions_stmt = db()->query("SELECT survey_id, id, question_text, question_type FROM survey_questions WHERE question_type = 'rating' OR question_type = 'multiple-choice'"); + $questions = $questions_stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC); + + $answers_stmt = db()->query("SELECT q.id as question_id, a.answer_text FROM survey_answers a JOIN survey_questions q ON a.question_id = q.id WHERE q.question_type = 'rating' OR q.question_type = 'multiple-choice'"); + $answers_by_question = $answers_stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_COLUMN); + $response = []; - - foreach ($surveys as $survey) { - $questions_stmt = db()->prepare("SELECT * FROM survey_questions WHERE survey_id = ? AND (question_type = 'rating' OR question_type = 'multiple-choice')"); - $questions_stmt->execute([$survey['id']]); - $questions = $questions_stmt->fetchAll(PDO::FETCH_ASSOC); - + foreach ($surveys as $survey_id => $survey_title) { $survey_data = [ - 'id' => $survey['id'], - 'title' => $survey['title'], + 'id' => $survey_id, + 'title' => $survey_title, 'questions' => [] ]; - foreach ($questions as $question) { - $answers_stmt = db()->prepare("SELECT answer_text, COUNT(*) as count FROM survey_answers WHERE question_id = ? GROUP BY answer_text"); - $answers_stmt->execute([$question['id']]); - $answers = $answers_stmt->fetchAll(PDO::FETCH_ASSOC); + if (isset($questions[$survey_id])) { + foreach ($questions[$survey_id] as $question) { + $question_id = $question['id']; + $question_data = [ + 'id' => $question_id, + 'question_text' => $question['question_text'], + 'type' => $question['question_type'], + ]; - $question_data = [ - 'id' => $question['id'], - 'question_text' => $question['question_text'], - 'type' => $question['question_type'], - 'answers' => [ - 'labels' => array_column($answers, 'answer_text'), - 'values' => array_column($answers, 'count') - ] - ]; - $survey_data['questions'][] = $question_data; + $answers = $answers_by_question[$question_id] ?? []; + + if ($question['question_type'] == 'multiple-choice') { + $answer_counts = []; + foreach ($answers as $answer_row) { + $options = preg_split('/,\s*/', $answer_row); + foreach ($options as $option) { + $trimmed_option = trim($option); + if (!empty($trimmed_option)) { + if (!isset($answer_counts[$trimmed_option])) { + $answer_counts[$trimmed_option] = 0; + } + $answer_counts[$trimmed_option]++; + } + } + } + $question_data['answers'] = [ + 'labels' => array_keys($answer_counts), + 'values' => array_values($answer_counts) + ]; + } else { // rating + $answer_counts = array_count_values($answers); + $question_data['answers'] = [ + 'labels' => array_keys($answer_counts), + 'values' => array_values($answer_counts) + ]; + } + $survey_data['questions'][] = $question_data; + } } $response[] = $survey_data; } @@ -60,4 +85,4 @@ switch ($action) { default: echo json_encode(['error' => 'Invalid action']); break; -} +} \ No newline at end of file diff --git a/assets/js/dashboard.js b/assets/js/dashboard.js index 8c3ff03..a81d355 100644 --- a/assets/js/dashboard.js +++ b/assets/js/dashboard.js @@ -63,12 +63,26 @@ document.addEventListener('DOMContentLoaded', function () { surveyRow.appendChild(col); new Chart(canvas.getContext('2d'), { - type: 'pie', + type: 'bar', data: { labels: question.answers.labels, datasets: [{ - data: question.answers.values + label: 'Count', + data: question.answers.values, + backgroundColor: 'rgba(54, 162, 235, 0.2)', + borderColor: 'rgba(54, 162, 235, 1)', + borderWidth: 1 }] + }, + options: { + scales: { + y: { + beginAtZero: true, + ticks: { + stepSize: 1 + } + } + } } }); } diff --git a/assets/pasted-20251007-215849-00ad5b16.png b/assets/pasted-20251007-215849-00ad5b16.png new file mode 100644 index 0000000..f4c8d39 Binary files /dev/null and b/assets/pasted-20251007-215849-00ad5b16.png differ diff --git a/assets/pasted-20251007-221904-8ecf5868.png b/assets/pasted-20251007-221904-8ecf5868.png new file mode 100644 index 0000000..0c103f8 Binary files /dev/null and b/assets/pasted-20251007-221904-8ecf5868.png differ diff --git a/dashboard.php b/dashboard.php index 8fddaa8..8a7f695 100644 --- a/dashboard.php +++ b/dashboard.php @@ -15,25 +15,33 @@ require_once 'templates/header.php';
-
-

Analytics Dashboard

- Back to Submissions -
- -
-
-
-
-

Submissions per Survey

-
-
- -
+
+
+
+

Analytics Dashboard

+ Back to Submissions
-
+
+
+
+
+
+

Submissions per Survey

+
+
+ +
+
+
+
-
+
+ +

Survey Question Analytics

+
+
+
diff --git a/db/migrations/011_add_options_to_survey_questions.sql b/db/migrations/011_add_options_to_survey_questions.sql new file mode 100644 index 0000000..68afd1f --- /dev/null +++ b/db/migrations/011_add_options_to_survey_questions.sql @@ -0,0 +1 @@ +ALTER TABLE survey_questions ADD COLUMN options TEXT NULL AFTER question_type; diff --git a/debug_log.txt b/debug_log.txt new file mode 100755 index 0000000..9ee1e2d --- /dev/null +++ b/debug_log.txt @@ -0,0 +1,220 @@ +--- NEW REQUEST --- +Surveys: +Array +( + [1] => Your True Flatlogic Feedback +) + +Questions: +Array +( + [1] => Array + ( + [0] => Array + ( + [survey_id] => 1 + [question_text] => What stopped you from upgrading after creating your app? + [question_type] => multiple-choice + ) + + ) + + [2] => Array + ( + [0] => Array + ( + [survey_id] => 1 + [question_text] => What would help you continue? + [question_type] => multiple-choice + ) + + ) + +) + +Answers by Question: +Array +( + [1] => Array + ( + [0] => The generated app didn’t look good enough, Bugs or errors on the platform, It used too many credits / hosting felt expensive + ) + + [2] => Array + ( + [0] => A short call with an engineer, Clearer tutorials/documentation, Access to a specific template/feature + ) + +) + + Processing Survey ID: 1 + Processing Question ID: + Answers for Question : +Array +( +) + + Processed Question Data: +Array +( + [id] => + [question_text] => What stopped you from upgrading after creating your app? + [type] => multiple-choice + [answers] => Array + ( + [labels] => Array + ( + ) + + [values] => Array + ( + ) + + ) + +) + +Final Response: +Array +( + [0] => Array + ( + [id] => 1 + [title] => Your True Flatlogic Feedback + [questions] => Array + ( + [0] => Array + ( + [id] => + [question_text] => What stopped you from upgrading after creating your app? + [type] => multiple-choice + [answers] => Array + ( + [labels] => Array + ( + ) + + [values] => Array + ( + ) + + ) + + ) + + ) + + ) + +) + +--- NEW REQUEST --- +Surveys: +Array +( + [1] => Your True Flatlogic Feedback +) + +Questions: +Array +( + [1] => Array + ( + [0] => Array + ( + [survey_id] => 1 + [question_text] => What stopped you from upgrading after creating your app? + [question_type] => multiple-choice + ) + + ) + + [2] => Array + ( + [0] => Array + ( + [survey_id] => 1 + [question_text] => What would help you continue? + [question_type] => multiple-choice + ) + + ) + +) + +Answers by Question: +Array +( + [1] => Array + ( + [0] => The generated app didn’t look good enough, Bugs or errors on the platform, It used too many credits / hosting felt expensive + ) + + [2] => Array + ( + [0] => A short call with an engineer, Clearer tutorials/documentation, Access to a specific template/feature + ) + +) + + Processing Survey ID: 1 + Processing Question ID: + Answers for Question : +Array +( +) + + Processed Question Data: +Array +( + [id] => + [question_text] => What stopped you from upgrading after creating your app? + [type] => multiple-choice + [answers] => Array + ( + [labels] => Array + ( + ) + + [values] => Array + ( + ) + + ) + +) + +Final Response: +Array +( + [0] => Array + ( + [id] => 1 + [title] => Your True Flatlogic Feedback + [questions] => Array + ( + [0] => Array + ( + [id] => + [question_text] => What stopped you from upgrading after creating your app? + [type] => multiple-choice + [answers] => Array + ( + [labels] => Array + ( + ) + + [values] => Array + ( + ) + + ) + + ) + + ) + + ) + +) + diff --git a/edit_survey.php b/edit_survey.php index 78600ca..965e873 100644 --- a/edit_survey.php +++ b/edit_survey.php @@ -50,18 +50,21 @@ require_once 'templates/header.php';
-
-
-
- - -
-
- - -
- -
+
+
+

Edit Survey

+
+
+ + +
+
+ + +
+ +
+
diff --git a/index.php b/index.php index 4580a5c..48c5449 100644 --- a/index.php +++ b/index.php @@ -34,20 +34,32 @@ require_once 'templates/header.php';
-
- -

No surveys available at the moment.

- - - -
-
- +
diff --git a/login.php b/login.php index 74fc091..f7d9786 100644 --- a/login.php +++ b/login.php @@ -58,23 +58,31 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
-
-

Login

- -
- -
-
- - +
+
+
+
+

Login

+ +
+ + +
+ + +
+
+ + +
+ + +

Don't have an account? Register here.

+
-
- - -
- - -

Don't have an account? Register here.

+
diff --git a/manage_questions.php b/manage_questions.php index 364470e..e058337 100644 --- a/manage_questions.php +++ b/manage_questions.php @@ -39,8 +39,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['question_text'])) { } // Handle question deletion -if (isset($_GET['delete_question'])) { - $question_id = $_GET['delete_question']; +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_question'])) { + $question_id = $_POST['delete_question']; $stmt = db()->prepare("DELETE FROM survey_questions WHERE id = ? AND survey_id = ?"); $stmt->execute([$question_id, $survey_id]); header("Location: manage_questions.php?survey_id=" . $survey_id); @@ -65,61 +65,69 @@ require_once 'templates/header.php';
-
-

Add New Question

-
-
- - -
-
- - -
- - -
+
+
+

Add New Question

+
+
+ + +
+
+ + +
+ + +
+

Existing Questions

-
- - - - - - - - - - - - - - - - - - - - - - - - - -
Question TextTypeOptionsActions
No questions added to this survey yet.
- Delete -
+
+ +
+

No questions added to this survey yet.

+
+ + +
+
+
+
+

+ Type:
+ + Options: + +

+
+ +
+
+ +
diff --git a/register.php b/register.php index 10b820a..0c7e680 100644 --- a/register.php +++ b/register.php @@ -55,34 +55,46 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
-
-

Register

- -
- - -
- -
-
- - +
+
+
+
+

Register

+ +
+ + +
+ + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + + +

Already have an account? Login here.

-
- - -
-
- - -
-
- - -
- - - +
+
diff --git a/submit_feedback.php b/submit_feedback.php index dcda342..93b91e2 100644 --- a/submit_feedback.php +++ b/submit_feedback.php @@ -45,7 +45,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $subject = "New Submission for Survey: " . $survey_title; $submission_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://" . $_SERVER['HTTP_HOST'] . '/view_submission.php?id=' . $submission_id; - $htmlBody = "

A new submission has been received for the survey: {$survey_title}

\n

Submitter: {$name} ({$email})

\n

Click here to view the full submission.

"; + $safe_name = htmlspecialchars($name); + $safe_email = htmlspecialchars($email); + $htmlBody = "

A new submission has been received for the survey: {$survey_title}

\n

Submitter: {$safe_name} ({$safe_email})

\n

Click here to view the full submission.

"; $textBody = "A new submission has been received for the survey: {$survey_title}. Submitter: {$name} ({$email}). View the submission here: {$submission_url}"; MailService::sendMail(null, $subject, $htmlBody, $textBody); diff --git a/surveys.php b/surveys.php index 910aa93..66f08b7 100644 --- a/surveys.php +++ b/surveys.php @@ -51,53 +51,52 @@ require_once 'templates/header.php'; -
-

Create New Survey

-
-
- - -
-
- - -
- -
+
+
+

Create New Survey

+
+
+ + +
+
+ + +
+ +
+

Existing Surveys

-
- - - - - - - - - - - - - - - - - - - - - - - - - -
TitleDescriptionCreated AtActions
No surveys created yet.
- Manage Questions - Edit -
+
+ +
+

No surveys created yet.

+
+ + +
+
+
+
+

+
+ +
+
+ +
diff --git a/templates/header.php b/templates/header.php index fe530f8..d152ada 100644 --- a/templates/header.php +++ b/templates/header.php @@ -46,12 +46,7 @@ $isSurveyPage = basename($_SERVER['PHP_SELF']) == 'survey.php'; Logout - - +
diff --git a/view_submission.php b/view_submission.php index 8112e6e..1cffcb5 100644 --- a/view_submission.php +++ b/view_submission.php @@ -3,8 +3,8 @@ session_start(); require_once 'db/config.php'; // Ensure admin is logged in -if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { - header('Location: admin.php'); +if (!isset($_SESSION['user_id']) || !in_array('Admin', $_SESSION['user_roles'])) { + header('Location: login.php'); exit; } @@ -43,30 +43,37 @@ require_once 'templates/header.php';
-

Survey:

+

Submission for ""

-

Submitter:

-

Email:

-

Submitted At:

-
-
- -
-
-

Answers

-
-
- - - +
+
Submission Details
+

Submitter:

+

Email:

+

Submitted At:

+
+
+
+
Answers
+
+ - - + + - - -
QuestionAnswer
+ + + + + + + + + + +