diff --git a/admin.php b/admin.php
new file mode 100644
index 0000000..fbf5a7e
--- /dev/null
+++ b/admin.php
@@ -0,0 +1,99 @@
+query("SELECT COUNT(*) FROM feedback_submissions");
+$total_records = $total_stmt->fetchColumn();
+$total_pages = ceil($total_records / $records_per_page);
+
+// Fetch submissions for the current page
+$submissions_stmt = db()->prepare("SELECT s.id, s.name, s.email, s.created_at, sv.title as survey_title, sv.id as survey_id FROM feedback_submissions s JOIN surveys sv ON s.survey_id = sv.id ORDER BY s.created_at DESC LIMIT :limit OFFSET :offset");
+$submissions_stmt->bindValue(':limit', $records_per_page, PDO::PARAM_INT);
+$submissions_stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
+$submissions_stmt->execute();
+$submissions = $submissions_stmt->fetchAll(PDO::FETCH_ASSOC);
+
+$pageTitle = "Admin - Feedback Submissions";
+require_once 'templates/header.php';
+?>
+
+
+
+
+
Feedback Submissions
+
+
+
+
+
+
+
+ | Survey |
+ Submitter |
+ Email |
+ Submitted At |
+ Answers |
+
+
+
+
+
+ | No feedback submissions yet. |
+
+
+
+
+ | = htmlspecialchars($submission['survey_title']) ?> |
+ = htmlspecialchars($submission['name']) ?> |
+ = htmlspecialchars($submission['email']) ?> |
+ = $submission['created_at'] ?> |
+
+ View Answers
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/api.php b/api.php
new file mode 100644
index 0000000..6fdecd6
--- /dev/null
+++ b/api.php
@@ -0,0 +1,63 @@
+ 'Unauthorized']);
+ exit;
+}
+
+$action = $_GET['action'] ?? '';
+
+switch ($action) {
+ case 'submissions_per_survey':
+ $stmt = db()->query("SELECT s.title, COUNT(fs.id) as submission_count FROM surveys s LEFT JOIN feedback_submissions fs ON s.id = fs.survey_id GROUP BY s.id");
+ $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ $labels = array_column($results, 'title');
+ $values = array_column($results, 'submission_count');
+ echo json_encode(['labels' => $labels, 'values' => $values]);
+ break;
+
+ case 'survey_question_analytics':
+ $surveys_stmt = db()->query("SELECT * FROM surveys");
+ $surveys = $surveys_stmt->fetchAll(PDO::FETCH_ASSOC);
+ $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);
+
+ $survey_data = [
+ '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);
+
+ $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;
+ }
+ $response[] = $survey_data;
+ }
+ echo json_encode($response);
+ break;
+
+ default:
+ echo json_encode(['error' => 'Invalid action']);
+ break;
+}
diff --git a/assets/css/custom.css b/assets/css/custom.css
new file mode 100644
index 0000000..a3336f7
--- /dev/null
+++ b/assets/css/custom.css
@@ -0,0 +1,174 @@
+
+@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&family=Georgia&display=swap');
+
+:root {
+ --primary-color: #1a1a1a;
+ --secondary-color: #198754; /* Changed from #4f46e5 */
+ --background-color: #f8f9fa;
+ --surface-color: #ffffff;
+ --text-color: #212529;
+ --border-radius: 0.5rem;
+ --border-radius-full: 9999px;
+ --spacing-1: 0.5rem;
+ --spacing-2: 1rem;
+ --spacing-3: 1.5rem;
+ --spacing-4: 2rem;
+}
+
+body {
+ background-color: var(--background-color);
+ color: var(--text-color);
+ font-family: 'Inter', sans-serif;
+ line-height: 1.6;
+ margin: 0;
+ padding: 0;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-family: 'Georgia', serif;
+ color: var(--primary-color);
+}
+
+.header {
+ padding: var(--spacing-2) 0;
+ border-bottom: 1px solid #dee2e6;
+}
+
+.logo {
+ font-family: 'Georgia', serif;
+ font-weight: bold;
+ font-size: 1.5rem;
+ color: var(--primary-color);
+ text-decoration: none;
+}
+
+.hero {
+ color: white;
+ padding: 6rem 0;
+ text-align: center;
+ background: linear-gradient(135deg, #198754, #20c997);
+ position: relative;
+ overflow: hidden;
+}
+
+.hero::before {
+ content: '';
+ position: absolute;
+ bottom: -150px;
+ left: -50px;
+ width: 300px;
+ height: 300px;
+ background: white;
+ opacity: 0.1;
+ border-radius: 50%;
+ transform: rotate(45deg);
+}
+
+.hero::after {
+ content: '';
+ position: absolute;
+ top: -100px;
+ right: -100px;
+ width: 400px;
+ height: 400px;
+ background: white;
+ opacity: 0.1;
+ border-radius: 50%;
+}
+
+
+.hero h1 {
+ font-size: 3.5rem;
+ font-weight: 700;
+ margin-bottom: var(--spacing-2);
+ color: white;
+}
+
+.hero p {
+ font-size: 1.25rem;
+ max-width: 600px;
+ margin: 0 auto;
+}
+
+.survey-section {
+ padding: 4rem 0;
+}
+
+.form-container {
+ background: var(--surface-color);
+ padding: var(--spacing-4);
+ border-radius: var(--border-radius);
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.05);
+ max-width: 600px;
+ margin: 0 auto;
+}
+
+.form-group {
+ margin-bottom: var(--spacing-3);
+}
+
+.form-label {
+ font-weight: bold;
+ display: block;
+ margin-bottom: var(--spacing-1);
+}
+
+.form-control {
+ width: 100%;
+ padding: 0.75rem 1rem;
+ border: 1px solid #ced4da;
+ border-radius: var(--border-radius);
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+
+.form-control:focus {
+ border-color: var(--secondary-color);
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);
+}
+
+.btn-primary {
+ background-color: var(--secondary-color);
+ border-color: var(--secondary-color);
+ color: white;
+ padding: 0.75rem 1.5rem;
+ font-size: 1rem;
+ font-weight: bold;
+ border-radius: var(--border-radius);
+ cursor: pointer;
+ transition: background-color 0.2s;
+ width: 100%;
+}
+
+.btn-primary:hover {
+ background-color: #157347;
+}
+
+.footer {
+ padding: var(--spacing-3) 0;
+ border-top: 1px solid #dee2e6;
+ text-align: center;
+ font-size: 0.9rem;
+ color: #6c757d;
+}
+
+.footer a {
+ color: var(--secondary-color);
+ text-decoration: none;
+}
+
+.footer a:hover {
+ text-decoration: underline;
+}
+
+#success-message {
+ text-align: center;
+ padding: 2rem;
+ background-color: #e8f5e9;
+ color: #2e7d32;
+ border-radius: var(--border-radius);
+}
+
+.hidden {
+ display: none;
+}
diff --git a/assets/js/dashboard.js b/assets/js/dashboard.js
new file mode 100644
index 0000000..8c3ff03
--- /dev/null
+++ b/assets/js/dashboard.js
@@ -0,0 +1,78 @@
+document.addEventListener('DOMContentLoaded', function () {
+ // Chart for submissions per survey
+ fetch('api.php?action=submissions_per_survey')
+ .then(response => response.json())
+ .then(data => {
+ const ctx = document.getElementById('submissions-chart').getContext('2d');
+ new Chart(ctx, {
+ type: 'bar',
+ data: {
+ labels: data.labels,
+ datasets: [{
+ label: '# of Submissions',
+ data: data.values,
+ backgroundColor: 'rgba(75, 192, 192, 0.2)',
+ borderColor: 'rgba(75, 192, 192, 1)',
+ borderWidth: 1
+ }]
+ },
+ options: {
+ scales: {
+ y: {
+ beginAtZero: true
+ }
+ }
+ }
+ });
+ });
+
+ // Charts for each survey's questions
+ fetch('api.php?action=survey_question_analytics')
+ .then(response => response.json())
+ .then(surveys => {
+ const container = document.getElementById('survey-charts-container');
+ surveys.forEach(survey => {
+ const surveyRow = document.createElement('div');
+ surveyRow.className = 'row';
+
+ const surveyTitle = document.createElement('h2');
+ surveyTitle.innerText = `Survey: ${survey.title}`;
+ container.appendChild(surveyTitle);
+ container.appendChild(surveyRow);
+
+ survey.questions.forEach(question => {
+ if (question.type === 'rating' || question.type === 'multiple-choice') {
+ const col = document.createElement('div');
+ col.className = 'col-md-6';
+
+ const card = document.createElement('div');
+ card.className = 'card mb-4';
+
+ const cardHeader = document.createElement('div');
+ cardHeader.className = 'card-header';
+ cardHeader.innerHTML = `
${question.question_text}
`;
+
+ const cardBody = document.createElement('div');
+ cardBody.className = 'card-body';
+
+ const canvas = document.createElement('canvas');
+ cardBody.appendChild(canvas);
+ card.appendChild(cardHeader);
+ card.appendChild(cardBody);
+ col.appendChild(card);
+ surveyRow.appendChild(col);
+
+ new Chart(canvas.getContext('2d'), {
+ type: 'pie',
+ data: {
+ labels: question.answers.labels,
+ datasets: [{
+ data: question.answers.values
+ }]
+ }
+ });
+ }
+ });
+ });
+ });
+});
diff --git a/assets/js/main.js b/assets/js/main.js
new file mode 100644
index 0000000..03850b0
--- /dev/null
+++ b/assets/js/main.js
@@ -0,0 +1,50 @@
+document.addEventListener('DOMContentLoaded', function () {
+ const surveyForm = document.getElementById('survey-form');
+ if (!surveyForm) return;
+
+ const successMessage = document.getElementById('success-message');
+ const formContainer = document.querySelector('.form-container');
+
+ surveyForm.addEventListener('submit', function (e) {
+ e.preventDefault();
+
+ const name = document.getElementById('name').value.trim();
+ const email = document.getElementById('email').value.trim();
+ const message = document.getElementById('message').value.trim();
+
+ if (name === '' || email === '' || message === '') {
+ alert('Please fill out all fields.');
+ return;
+ }
+
+ if (!validateEmail(email)) {
+ alert('Please enter a valid email address.');
+ return;
+ }
+
+ const formData = new FormData(this);
+
+ fetch('submit_feedback.php', {
+ method: 'POST',
+ body: formData
+ })
+ .then(response => response.json())
+ .then(data => {
+ if (data.success) {
+ formContainer.classList.add('hidden');
+ successMessage.classList.remove('hidden');
+ } else {
+ alert('An error occurred: ' + data.error);
+ }
+ })
+ .catch(error => {
+ console.error('Error:', error);
+ alert('A server error occurred. Please try again later.');
+ });
+ });
+
+ function validateEmail(email) {
+ const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+ return re.test(String(email).toLowerCase());
+ }
+});
diff --git a/dashboard.php b/dashboard.php
new file mode 100644
index 0000000..8fddaa8
--- /dev/null
+++ b/dashboard.php
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/db/config.php b/db/config.php
index bb98f7d..bc6f7cb 100644
--- a/db/config.php
+++ b/db/config.php
@@ -6,12 +6,52 @@ define('DB_USER', 'app_30953');
define('DB_PASS', 'e45f2778-db1f-450c-99c6-29efb4601472');
function db() {
- static $pdo;
- if (!$pdo) {
- $pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [
- PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
- PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
- ]);
- }
- return $pdo;
+ static $pdo;
+ if (!$pdo) {
+ try {
+ // Connect to MySQL server without specifying a database
+ $pdo = new PDO('mysql:host='.DB_HOST.';charset=utf8mb4', DB_USER, DB_PASS, [
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
+ ]);
+
+ // Create the database if it doesn't exist
+ $pdo->exec('CREATE DATABASE IF NOT EXISTS `'.DB_NAME.'`');
+
+ // Re-connect to the specific database
+ $pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
+ ]);
+
+ } catch (PDOException $e) {
+ // If database creation fails, it's a critical error.
+ error_log('Database connection or creation failed: ' . $e->getMessage());
+ // Exit or handle the error gracefully. For a web request, you might show a generic error page.
+ http_response_code(500);
+ echo "Database connection failed. Please check the server logs.";
+ exit;
+ }
+ }
+ return $pdo;
}
+
+function run_migrations() {
+ $pdo = db();
+ $migrations_dir = __DIR__ . '/migrations';
+ if (!is_dir($migrations_dir)) {
+ return;
+ }
+ $files = glob($migrations_dir . '/*.sql');
+ foreach ($files as $file) {
+ $sql = file_get_contents($file);
+ try {
+ $pdo->exec($sql);
+ } catch (PDOException $e) {
+ // Log error or handle it as needed
+ error_log("Migration failed for file: " . basename($file) . " with error: " . $e->getMessage());
+ }
+ }
+}
+
+run_migrations();
\ No newline at end of file
diff --git a/db/migrations/001_create_feedback_submissions_table.sql b/db/migrations/001_create_feedback_submissions_table.sql
new file mode 100644
index 0000000..9a7d885
--- /dev/null
+++ b/db/migrations/001_create_feedback_submissions_table.sql
@@ -0,0 +1,7 @@
+CREATE TABLE IF NOT EXISTS feedback_submissions (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ email VARCHAR(255) NOT NULL,
+ message TEXT NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
\ No newline at end of file
diff --git a/db/migrations/002_create_surveys_table.sql b/db/migrations/002_create_surveys_table.sql
new file mode 100644
index 0000000..64ad19d
--- /dev/null
+++ b/db/migrations/002_create_surveys_table.sql
@@ -0,0 +1,6 @@
+CREATE TABLE IF NOT EXISTS `surveys` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `title` VARCHAR(255) NOT NULL,
+ `description` TEXT,
+ `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
\ No newline at end of file
diff --git a/db/migrations/003_create_survey_questions_table.sql b/db/migrations/003_create_survey_questions_table.sql
new file mode 100644
index 0000000..65a3ad4
--- /dev/null
+++ b/db/migrations/003_create_survey_questions_table.sql
@@ -0,0 +1,9 @@
+CREATE TABLE IF NOT EXISTS `survey_questions` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `survey_id` INT NOT NULL,
+ `question_text` TEXT NOT NULL,
+ `question_type` VARCHAR(50) NOT NULL, -- e.g., 'text', 'textarea', 'rating', 'multiple-choice'
+ `options` TEXT, -- For multiple-choice questions, store options as a JSON array or comma-separated values
+ `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (`survey_id`) REFERENCES `surveys`(`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
\ No newline at end of file
diff --git a/db/migrations/004_add_survey_id_to_feedback_submissions.sql b/db/migrations/004_add_survey_id_to_feedback_submissions.sql
new file mode 100644
index 0000000..3a9e84f
--- /dev/null
+++ b/db/migrations/004_add_survey_id_to_feedback_submissions.sql
@@ -0,0 +1 @@
+ALTER TABLE `feedback_submissions` ADD COLUMN `survey_id` INT NULL AFTER `id`;
\ No newline at end of file
diff --git a/db/migrations/005_create_survey_answers_table.sql b/db/migrations/005_create_survey_answers_table.sql
new file mode 100644
index 0000000..925c314
--- /dev/null
+++ b/db/migrations/005_create_survey_answers_table.sql
@@ -0,0 +1,9 @@
+CREATE TABLE IF NOT EXISTS `survey_answers` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `submission_id` INT NOT NULL,
+ `question_id` INT NOT NULL,
+ `answer_text` TEXT,
+ `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (`submission_id`) REFERENCES `feedback_submissions`(`id`) ON DELETE CASCADE,
+ FOREIGN KEY (`question_id`) REFERENCES `survey_questions`(`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
\ No newline at end of file
diff --git a/db/migrations/006_create_users_table.sql b/db/migrations/006_create_users_table.sql
new file mode 100644
index 0000000..195077e
--- /dev/null
+++ b/db/migrations/006_create_users_table.sql
@@ -0,0 +1,7 @@
+CREATE TABLE IF NOT EXISTS `users` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `username` VARCHAR(50) NOT NULL UNIQUE,
+ `email` VARCHAR(100) NOT NULL UNIQUE,
+ `password` VARCHAR(255) NOT NULL,
+ `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
\ No newline at end of file
diff --git a/db/migrations/007_create_roles_table.sql b/db/migrations/007_create_roles_table.sql
new file mode 100644
index 0000000..df1956e
--- /dev/null
+++ b/db/migrations/007_create_roles_table.sql
@@ -0,0 +1,4 @@
+CREATE TABLE IF NOT EXISTS `roles` (
+ `id` INT AUTO_INCREMENT PRIMARY KEY,
+ `role_name` VARCHAR(50) NOT NULL UNIQUE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
\ No newline at end of file
diff --git a/db/migrations/008_create_user_roles_table.sql b/db/migrations/008_create_user_roles_table.sql
new file mode 100644
index 0000000..6bdb97d
--- /dev/null
+++ b/db/migrations/008_create_user_roles_table.sql
@@ -0,0 +1,7 @@
+CREATE TABLE IF NOT EXISTS `user_roles` (
+ `user_id` INT NOT NULL,
+ `role_id` INT NOT NULL,
+ PRIMARY KEY (`user_id`, `role_id`),
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
+ FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
\ No newline at end of file
diff --git a/db/migrations/009_insert_default_roles.sql b/db/migrations/009_insert_default_roles.sql
new file mode 100644
index 0000000..6438db4
--- /dev/null
+++ b/db/migrations/009_insert_default_roles.sql
@@ -0,0 +1 @@
+INSERT INTO `roles` (`role_name`) VALUES ('Admin'), ('Respondent');
\ No newline at end of file
diff --git a/edit_survey.php b/edit_survey.php
new file mode 100644
index 0000000..78600ca
--- /dev/null
+++ b/edit_survey.php
@@ -0,0 +1,72 @@
+prepare("SELECT * FROM surveys WHERE id = ?");
+$survey_stmt->execute([$survey_id]);
+$survey = $survey_stmt->fetch();
+if (!$survey) {
+ header('Location: surveys.php');
+ exit;
+}
+
+// Handle form submission for updating survey
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['title'])) {
+ $title = trim($_POST['title']);
+ $description = trim($_POST['description']);
+
+ if (!empty($title)) {
+ $stmt = db()->prepare("UPDATE surveys SET title = ?, description = ? WHERE id = ?");
+ $stmt->execute([$title, $description, $survey_id]);
+ header("Location: surveys.php"); // Redirect to the survey list
+ exit;
+ }
+}
+
+$pageTitle = "Edit Survey";
+require_once 'templates/header.php';
+?>
+
+
+
+
+
+
diff --git a/export.php b/export.php
new file mode 100644
index 0000000..e5d8396
--- /dev/null
+++ b/export.php
@@ -0,0 +1,66 @@
+query("SELECT
+ s.id as submission_id,
+ s.name as submitter_name,
+ s.email as submitter_email,
+ s.created_at as submission_date,
+ sv.title as survey_title,
+ q.question_text,
+ a.answer_text
+FROM feedback_submissions s
+JOIN surveys sv ON s.survey_id = sv.id
+LEFT JOIN survey_answers a ON s.id = a.submission_id
+LEFT JOIN survey_questions q ON a.question_id = q.id
+ORDER BY s.created_at DESC, q.created_at ASC");
+
+$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+// Set headers for CSV download
+header('Content-Type: text/csv; charset=utf-8');
+header('Content-Disposition: attachment; filename=feedback_submissions_' . date('Y-m-d') . '.csv');
+
+$output = fopen('php://output', 'w');
+
+// Get all unique questions in order
+$questions_stmt = db()->query("SELECT DISTINCT question_text FROM survey_questions ORDER BY created_at ASC");
+$question_headers = $questions_stmt->fetchAll(PDO::FETCH_COLUMN);
+
+// Output the column headings
+$headers = array_merge(['Submission ID', 'Submitter', 'Email', 'Date', 'Survey'], $question_headers);
+fputcsv($output, $headers);
+
+// Process the results
+$submissions = [];
+foreach ($results as $row) {
+ $submissions[$row['submission_id']]['details'] = [
+ 'submission_id' => $row['submission_id'],
+ 'submitter_name' => $row['submitter_name'],
+ 'submitter_email' => $row['submitter_email'],
+ 'submission_date' => $row['submission_date'],
+ 'survey_title' => $row['survey_title']
+ ];
+ $submissions[$row['submission_id']]['answers'][$row['question_text']] = $row['answer_text'];
+}
+
+// Write rows to CSV
+foreach ($submissions as $submission_id => $data) {
+ $row = $data['details'];
+ foreach ($question_headers as $question) {
+ $row[] = $data['answers'][$question] ?? '';
+ }
+ fputcsv($output, $row);
+}
+
+fclose($output);
+exit;
+?>
\ No newline at end of file
diff --git a/index.php b/index.php
index 7205f3d..4580a5c 100644
--- a/index.php
+++ b/index.php
@@ -1,150 +1,74 @@
query("SELECT COUNT(*) FROM surveys");
+$total_records = $total_stmt->fetchColumn();
+$total_pages = ceil($total_records / $records_per_page);
+
+// Fetch surveys for the current page
+$surveys_stmt = db()->prepare("SELECT * FROM surveys ORDER BY created_at DESC LIMIT :limit OFFSET :offset");
+$surveys_stmt->bindValue(':limit', $records_per_page, PDO::PARAM_INT);
+$surveys_stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
+$surveys_stmt->execute();
+$surveys = $surveys_stmt->fetchAll();
+
+$pageTitle = "Available Surveys";
+$description = "Choose a survey to provide your feedback.";
+
+require_once 'templates/header.php';
?>
-
-
-
-
-
- New Style
+
+
+
+
+
Available Surveys
+
Please choose one of the surveys below to provide your feedback.
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Analyzing your requirements and generating your website…
-
- Loading…
-
-
= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.
-
This page will update automatically as the plan is implemented.
-
Runtime: PHP = htmlspecialchars($phpVersion) ?> — UTC = htmlspecialchars($now) ?>
-
-
-
-
-
diff --git a/login.php b/login.php
new file mode 100644
index 0000000..74fc091
--- /dev/null
+++ b/login.php
@@ -0,0 +1,85 @@
+prepare("SELECT * FROM users WHERE username = ?");
+ $stmt->execute([$username]);
+ $user = $stmt->fetch();
+
+ if ($user && password_verify($password, $user['password'])) {
+ // Get user roles
+ $roles_stmt = $pdo->prepare("SELECT r.role_name FROM user_roles ur JOIN roles r ON ur.role_id = r.id WHERE ur.user_id = ?");
+ $roles_stmt->execute([$user['id']]);
+ $roles = $roles_stmt->fetchAll(PDO::FETCH_COLUMN);
+
+ // Store user info in session
+ $_SESSION['user_id'] = $user['id'];
+ $_SESSION['username'] = $user['username'];
+ $_SESSION['email'] = $user['email'];
+ $_SESSION['user_roles'] = $roles;
+
+ // Redirect based on role
+ if (in_array('Admin', $roles)) {
+ header('Location: admin.php');
+ } else {
+ header('Location: index.php');
+ }
+ exit;
+ } else {
+ $error = 'Invalid username or password.';
+ }
+ }
+}
+?>
+
+
+
+
+
+
diff --git a/logout.php b/logout.php
new file mode 100644
index 0000000..4e97304
--- /dev/null
+++ b/logout.php
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/manage_questions.php b/manage_questions.php
new file mode 100644
index 0000000..364470e
--- /dev/null
+++ b/manage_questions.php
@@ -0,0 +1,136 @@
+prepare("SELECT * FROM surveys WHERE id = ?");
+$survey_stmt->execute([$survey_id]);
+$survey = $survey_stmt->fetch();
+if (!$survey) {
+ header('Location: surveys.php');
+ exit;
+}
+
+// Handle form submission for new question
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['question_text'])) {
+ $question_text = trim($_POST['question_text']);
+ $question_type = trim($_POST['question_type']);
+ $options = ($question_type === 'multiple-choice') ? trim($_POST['options']) : null;
+
+ if (!empty($question_text) && !empty($question_type)) {
+ $stmt = db()->prepare("INSERT INTO survey_questions (survey_id, question_text, question_type, options) VALUES (?, ?, ?, ?)");
+ $stmt->execute([$survey_id, $question_text, $question_type, $options]);
+ header("Location: manage_questions.php?survey_id=" . $survey_id);
+ exit;
+ }
+}
+
+// Handle question deletion
+if (isset($_GET['delete_question'])) {
+ $question_id = $_GET['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);
+ exit;
+}
+
+// Fetch all questions for the survey
+$questions_stmt = db()->prepare("SELECT * FROM survey_questions WHERE survey_id = ? ORDER BY created_at ASC");
+$questions_stmt->execute([$survey_id]);
+$questions = $questions_stmt->fetchAll();
+
+$pageTitle = "Manage Questions for " . htmlspecialchars($survey['title']);
+require_once 'templates/header.php';
+?>
+
+
+
+
+
+
Manage Questions for "= htmlspecialchars($survey['title']) ?>"
+
Back to Surveys
+
+
+
+
+
+
+
Existing Questions
+
+
+
+
+ | Question Text |
+ Type |
+ Options |
+ Actions |
+
+
+
+
+
+ | No questions added to this survey yet. |
+
+
+
+
+ | = htmlspecialchars($question['question_text']) ?> |
+ = htmlspecialchars($question['question_type']) ?> |
+ = htmlspecialchars($question['options'] ?? '') ?> |
+
+ Delete
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/privacy.php b/privacy.php
new file mode 100644
index 0000000..24a30ca
--- /dev/null
+++ b/privacy.php
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ - Your Real Feedback
+
+
+
+
+
+
+
+
+ Privacy Policy
+ This is a placeholder for your privacy policy. You should replace this with your own terms.
+ Information we collect and why we collect it...
+ How we use that information...
+ etc...
+
+
+
+
+
+
diff --git a/register.php b/register.php
new file mode 100644
index 0000000..4719df0
--- /dev/null
+++ b/register.php
@@ -0,0 +1,89 @@
+prepare("SELECT * FROM users WHERE username = ? OR email = ?");
+ $stmt->execute([$username, $email]);
+ if ($stmt->fetch()) {
+ $error = 'Username or email already exists.';
+ } else {
+ // Insert new user
+ $hashed_password = password_hash($password, PASSWORD_DEFAULT);
+ $user_stmt = $pdo->prepare("INSERT INTO users (username, email, password) VALUES (?, ?, ?)");
+ $user_stmt->execute([$username, $email, $hashed_password]);
+ $user_id = $pdo->lastInsertId();
+
+ // Assign default role (Respondent)
+ $role_stmt = $pdo->prepare("SELECT id FROM roles WHERE role_name = ?");
+ $role_stmt->execute(['Respondent']);
+ $role_id = $role_stmt->fetchColumn();
+ if ($role_id) {
+ $user_role_stmt = $pdo->prepare("INSERT INTO user_roles (user_id, role_id) VALUES (?, ?)");
+ $user_role_stmt->execute([$user_id, $role_id]);
+ }
+
+ $success = 'Registration successful! You can now login.';
+ }
+ }
+}
+?>
+
+
+
+
+
+
diff --git a/submit_feedback.php b/submit_feedback.php
new file mode 100644
index 0000000..9f3146c
--- /dev/null
+++ b/submit_feedback.php
@@ -0,0 +1,60 @@
+ false, 'error' => 'Invalid request'];
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ $name = trim($_POST['name'] ?? '');
+ $email = trim($_POST['email'] ?? '');
+ $survey_id = trim($_POST['survey_id'] ?? '');
+ $answers = $_POST['answers'] ?? [];
+
+ if (empty($name) || empty($email) || empty($survey_id) || empty($answers)) {
+ $response['error'] = 'Please fill out all fields.';
+ } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
+ $response['error'] = 'Invalid email format.';
+ } else {
+ $pdo = db();
+ try {
+ $pdo->beginTransaction();
+
+ // Insert into feedback_submissions
+ $stmt = $pdo->prepare("INSERT INTO feedback_submissions (name, email, survey_id) VALUES (?, ?, ?)");
+ $stmt->execute([$name, $email, $survey_id]);
+ $submission_id = $pdo->lastInsertId();
+
+ // Insert into survey_answers
+ $answer_stmt = $pdo->prepare("INSERT INTO survey_answers (submission_id, question_id, answer_text) VALUES (?, ?, ?)");
+ foreach ($answers as $question_id => $answer_text) {
+ if (!empty($answer_text)) {
+ $answer_stmt->execute([$submission_id, $question_id, $answer_text]);
+ }
+ }
+
+ $pdo->commit();
+ $response['success'] = true;
+ unset($response['error']);
+
+ // Send email notification
+ require_once __DIR__ . '/mail/MailService.php';
+ $survey_stmt = $pdo->prepare("SELECT title FROM surveys WHERE id = ?");
+ $survey_stmt->execute([$survey_id]);
+ $survey_title = $survey_stmt->fetchColumn();
+
+ $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.
";
+ $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);
+
+ } catch (PDOException $e) {
+ $pdo->rollBack();
+ error_log($e->getMessage());
+ $response['error'] = 'Database error. Could not submit feedback.';
+ }
+ }
+}
+
+echo json_encode($response);
diff --git a/survey.php b/survey.php
new file mode 100644
index 0000000..392a8c3
--- /dev/null
+++ b/survey.php
@@ -0,0 +1,100 @@
+prepare("SELECT * FROM surveys WHERE id = ?");
+$survey_stmt->execute([$survey_id]);
+$survey = $survey_stmt->fetch();
+
+// If survey doesn't exist, show an error or redirect
+if (!$survey) {
+ $pageTitle = "Survey Not Found";
+ require_once 'templates/header.php';
+ echo "";
+ require_once 'templates/footer.php';
+ exit;
+}
+
+// Fetch questions for the survey
+$questions_stmt = db()->prepare("SELECT * FROM survey_questions WHERE survey_id = ? ORDER BY created_at ASC");
+$questions_stmt->execute([$survey_id]);
+$questions = $questions_stmt->fetchAll();
+
+$pageTitle = htmlspecialchars($survey['title']);
+$description = htmlspecialchars($survey['description']);
+
+require_once 'templates/header.php';
+?>
+
+
+
+
+
= htmlspecialchars($survey['title']) ?>
+
= htmlspecialchars($survey['description']) ?>
+
+
+
+
+
+
+
Thank you!
+
Your feedback has been submitted successfully. We appreciate you taking the time to help us improve.
+
+
+
+
+
+
+
+
diff --git a/surveys.php b/surveys.php
new file mode 100644
index 0000000..910aa93
--- /dev/null
+++ b/surveys.php
@@ -0,0 +1,124 @@
+prepare("INSERT INTO surveys (title, description) VALUES (?, ?)");
+ $stmt->execute([$title, $description]);
+ header("Location: surveys.php"); // Redirect to avoid form resubmission
+ exit;
+ }
+}
+
+// Pagination
+$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
+$records_per_page = 10;
+$offset = ($page - 1) * $records_per_page;
+
+// Get total number of surveys
+$total_stmt = db()->query("SELECT COUNT(*) FROM surveys");
+$total_records = $total_stmt->fetchColumn();
+$total_pages = ceil($total_records / $records_per_page);
+
+// Fetch surveys for the current page
+$surveys_stmt = db()->prepare("SELECT * FROM surveys ORDER BY created_at DESC LIMIT :limit OFFSET :offset");
+$surveys_stmt->bindValue(':limit', $records_per_page, PDO::PARAM_INT);
+$surveys_stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
+$surveys_stmt->execute();
+$surveys = $surveys_stmt->fetchAll();
+
+$pageTitle = "Manage Surveys";
+require_once 'templates/header.php';
+?>
+
+
+
+
+
+
Manage Surveys
+
Back to Submissions
+
+
+
+
+
+
+
Existing Surveys
+
+
+
+
+ | Title |
+ Description |
+ Created At |
+ Actions |
+
+
+
+
+
+ | No surveys created yet. |
+
+
+
+
+ | = htmlspecialchars($survey['title']) ?> |
+ = htmlspecialchars($survey['description']) ?> |
+ = $survey['created_at'] ?> |
+
+ Manage Questions
+ Edit
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/footer.php b/templates/footer.php
new file mode 100644
index 0000000..f15c979
--- /dev/null
+++ b/templates/footer.php
@@ -0,0 +1,10 @@
+
+
+
+