surveymonkey software

This commit is contained in:
Flatlogic Bot 2025-10-08 11:52:31 +00:00
parent c004a42556
commit fd6d509567
28 changed files with 1733 additions and 150 deletions

190
admin/analytics.php Normal file
View File

@ -0,0 +1,190 @@
<?php
require_once __DIR__ . '/partials/header.php';
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
require_once __DIR__ . '/../db/config.php';
try {
$pdo = db();
// Fetch all survey responses
$stmt = $pdo->query("SELECT * FROM survey_responses ORDER BY created_at DESC");
$responses = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Calculate basic statistics
$total_responses = count($responses);
$satisfaction_counts = [
'very_satisfied' => 0,
'satisfied' => 0,
'neutral' => 0,
'unsatisfied' => 0,
'very_unsatisfied' => 0,
];
$how_heard_counts = [
'social_media' => 0,
'friend' => 0,
'search_engine' => 0,
'advertisement' => 0,
'other' => 0,
];
foreach ($responses as $response) {
if (isset($satisfaction_counts[$response['satisfaction']])) {
$satisfaction_counts[$response['satisfaction']]++;
}
if (isset($how_heard_counts[$response['how_heard']])) {
$how_heard_counts[$response['how_heard']]++;
}
}
} catch (PDOException $e) {
$error = "Database error: " . $e->getMessage();
}
?>
<div class="container-fluid">
<div class="d-sm-flex justify-content-between align-items-center mb-4">
<h3 class="text-dark mb-0">Analytics & Reporting</h3>
</div>
<?php if (isset($error)): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
<?php else: ?>
<div class="row">
<!-- Total Responses Card -->
<div class="col-md-6 col-xl-3 mb-4">
<div class="card shadow border-start-primary py-2">
<div class="card-body">
<div class="row align-items-center no-gutters">
<div class="col me-2">
<div class="text-uppercase text-primary fw-bold text-xs mb-1"><span>Total Responses</span></div>
<div class="text-dark fw-bold h5 mb-0"><span><?php echo $total_responses; ?></span></div>
</div>
<div class="col-auto"><i class="fas fa-comments fa-2x text-gray-300"></i></div>
</div>
</div>
</div>
</div>
</div>
<!-- Satisfaction Distribution Chart -->
<div class="row">
<div class="col-lg-7 col-xl-8">
<div class="card shadow mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h6 class="text-primary fw-bold m-0">Satisfaction Distribution</h6>
</div>
<div class="card-body">
<div class="chart-container" style="position: relative; height:40vh; width:80vw">
<canvas id="satisfactionChart"></canvas>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
const ctx = document.getElementById('satisfactionChart').getContext('2d');
const satisfactionData = <?php echo json_encode(array_values($satisfaction_counts)); ?>;
const satisfactionLabels = <?php echo json_encode(array_map(function($label) {
return ucwords(str_replace('_', ' ', $label));
}, array_keys($satisfaction_counts))); ?>;
new Chart(ctx, {
type: 'bar',
data: {
labels: satisfactionLabels,
datasets: [{
label: 'Number of Responses',
data: satisfactionData,
backgroundColor: [
'rgba(75, 192, 192, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(255, 159, 64, 0.2)',
'rgba(255, 99, 132, 0.2)'
],
borderColor: [
'rgba(75, 192, 192, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(255, 159, 64, 1)',
'rgba(255, 99, 132, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true,
ticks: {
stepSize: 1
}
}
},
responsive: true,
maintainAspectRatio: false
}
});
});
</script>
</div>
</div>
</div>
<div class="col-lg-5 col-xl-4">
<div class="card shadow mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h6 class="text-primary fw-bold m-0">Referral Sources</h6>
</div>
<div class="card-body">
<div class="chart-container" style="position: relative; height:40vh; width:80vw">
<canvas id="howHeardChart"></canvas>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
const ctx = document.getElementById('howHeardChart').getContext('2d');
const howHeardData = <?php echo json_encode(array_values($how_heard_counts)); ?>;
const howHeardLabels = <?php echo json_encode(array_map(function($label) {
return ucwords(str_replace('_', ' ', $label));
}, array_keys($how_heard_counts))); ?>;
new Chart(ctx, {
type: 'pie',
data: {
labels: howHeardLabels,
datasets: [{
label: 'Number of Responses',
data: howHeardData,
backgroundColor: [
'rgba(75, 192, 192, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(255, 159, 64, 0.2)',
'rgba(255, 99, 132, 0.2)'
],
borderColor: [
'rgba(75, 192, 192, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(255, 159, 64, 1)',
'rgba(255, 99, 132, 1)'
],
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
});
</script>
</div>
</div>
</div>
</div>
<?php endif; ?>
</div>
<?php require_once __DIR__ . '/partials/footer.php'; ?>

94
admin/edit_page.php Normal file
View File

@ -0,0 +1,94 @@
<?php
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/partials/header.php';
$page_id = $_GET['id'] ?? null;
if (!$page_id) {
header('Location: pages.php');
exit();
}
// Handle form submission for updating the page
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_page'])) {
$title = trim($_POST['title']);
$slug = trim($_POST['slug']);
$content = trim($_POST['content']);
$is_published = isset($_POST['is_published']) ? 1 : 0;
$menu_order = (int)($_POST['menu_order'] ?? 0);
if (empty($title) || empty($slug)) {
$error = "Title and slug are required.";
} else {
// Check if slug already exists for another page
$stmt = db()->prepare("SELECT id FROM pages WHERE slug = ? AND id != ?");
$stmt->execute([$slug, $page_id]);
if ($stmt->fetch()) {
$error = "Slug already exists. Please choose a unique one.";
} else {
$stmt = db()->prepare("UPDATE pages SET title = ?, slug = ?, content = ?, is_published = ?, menu_order = ? WHERE id = ?");
if ($stmt->execute([$title, $slug, $content, $is_published, $menu_order, $page_id])) {
$success = "Page updated successfully!";
} else {
$error = "Failed to update page.";
}
}
}
}
// Fetch the page data
$stmt = db()->prepare("SELECT * FROM pages WHERE id = ?");
$stmt->execute([$page_id]);
$page = $stmt->fetch();
if (!$page) {
header('Location: pages.php');
exit();
}
?>
<div class="container">
<h1>Edit Page</h1>
<?php if (isset($error)): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
<?php endif; ?>
<?php if (isset($success)): ?>
<div class="alert alert-success"><?php echo htmlspecialchars($success); ?></div>
<?php endif; ?>
<div class="card">
<div class="card-header">
<h2>Editing '<?php echo htmlspecialchars($page['title']); ?>'</h2>
</div>
<div class="card-body">
<form action="edit_page.php?id=<?php echo $page['id']; ?>" method="POST">
<div class="form-group">
<label for="title">Title</label>
<input type="text" id="title" name="title" class="form-control" value="<?php echo htmlspecialchars($page['title']); ?>" required>
</div>
<div class="form-group">
<label for="slug">Slug</label>
<input type="text" id="slug" name="slug" class="form-control" value="<?php echo htmlspecialchars($page['slug']); ?>" required>
<small>The slug is the URL-friendly version of the name. E.g., "about-us"</small>
</div>
<div class="form-group">
<label for="content">Content</label>
<textarea id="content" name="content" class="form-control" rows="10"><?php echo htmlspecialchars($page['content']); ?></textarea>
</div>
<div class="form-group">
<label for="menu_order">Menu Order</label>
<input type="number" id="menu_order" name="menu_order" class="form-control" value="<?php echo htmlspecialchars($page['menu_order']); ?>">
</div>
<div class="form-check">
<input type="checkbox" id="is_published" name="is_published" class="form-check-input" value="1" <?php echo $page['is_published'] ? 'checked' : ''; ?>>
<label for="is_published" class="form-check-label">Publish?</label>
</div>
<button type="submit" name="update_page" class="btn btn-primary mt-3">Update Page</button>
<a href="pages.php" class="btn btn-secondary mt-3">Back to Pages</a>
</form>
</div>
</div>
</div>
<?php require_once __DIR__ . '/partials/footer.php'; ?>

92
admin/edit_user.php Normal file
View File

@ -0,0 +1,92 @@
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
require_once '../db/config.php';
$user_id = $_GET['id'] ?? null;
if (!$user_id) {
header('Location: users.php');
exit;
}
$pdo = db();
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username']);
$role = $_POST['role'];
$password = $_POST['password'];
try {
if (!empty($password)) {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare('UPDATE users SET username = ?, role = ?, password = ? WHERE id = ?');
$stmt->execute([$username, $role, $hashed_password, $user_id]);
} else {
$stmt = $pdo->prepare('UPDATE users SET username = ?, role = ? WHERE id = ?');
$stmt->execute([$username, $role, $user_id]);
}
header('Location: users.php?updated=true');
exit;
} catch (PDOException $e) {
$error_message = "Error updating user: " . $e->getMessage();
}
}
// Fetch user data
try {
$stmt = $pdo->prepare('SELECT username, role FROM users WHERE id = ?');
$stmt->execute([$user_id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user) {
header('Location: users.php');
exit;
}
} catch (PDOException $e) {
die("Error fetching user data: " . $e->getMessage());
}
$page_title = "Edit User";
include 'partials/header.php';
?>
<div class="container-fluid">
<h3 class="text-dark mb-4">Edit User</h3>
<?php if (!empty($error_message)): ?>
<div class="alert alert-danger"><?php echo $error_message; ?></div>
<?php endif; ?>
<div class="card shadow">
<div class="card-header py-3">
<p class="text-primary m-0 fw-bold">Edit User Details</p>
</div>
<div class="card-body">
<form action="edit_user.php?id=<?php echo $user_id; ?>" method="POST">
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" value="<?php echo htmlspecialchars($user['username']); ?>" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">New Password (leave blank to keep current password)</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<div class="mb-3">
<label for="role" class="form-label">Role</label>
<select class="form-select" id="role" name="role">
<option value="admin" <?php echo ($user['role'] === 'admin') ? 'selected' : ''; ?>>Admin</option>
<option value="editor" <?php echo ($user['role'] === 'editor') ? 'selected' : ''; ?>>Editor</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Save Changes</button>
<a href="users.php" class="btn btn-secondary">Cancel</a>
</form>
</div>
</div>
</div>
<?php include 'partials/footer.php'; ?>

35
admin/export.php Normal file
View File

@ -0,0 +1,35 @@
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
require_once __DIR__ . '/../db/config.php';
try {
$pdo = db();
$stmt = $pdo->query("SELECT id, name, email, satisfaction, message, created_at FROM survey_responses ORDER BY created_at DESC");
$responses = $stmt->fetchAll(PDO::FETCH_ASSOC);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="survey_responses.csv"');
$output = fopen('php://output', 'w');
// Add header row
fputcsv($output, array('ID', 'Name', 'Email', 'Satisfaction', 'Message', 'Submitted At'));
// Add data rows
foreach ($responses as $response) {
fputcsv($output, $response);
}
fclose($output);
exit;
} catch (PDOException $e) {
// In a real app, you'd log this error.
die("Error: Could not export data.");
}
?>

88
admin/index.php Normal file
View File

@ -0,0 +1,88 @@
<?php
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/partials/header.php';
$pdo = db();
// Get total users
$stmt_users = $pdo->query("SELECT COUNT(*) FROM users");
$total_users = $stmt_users->fetchColumn();
// Get total pages
$stmt_pages = $pdo->query("SELECT COUNT(*) FROM pages");
$total_pages = $stmt_pages->fetchColumn();
// Get recent pages
$stmt_recent_pages = $pdo->query("SELECT * FROM pages ORDER BY created_at DESC LIMIT 5");
$recent_pages = $stmt_recent_pages->fetchAll();
?>
<div class="container-fluid">
<h1 class="mt-4">Admin Dashboard</h1>
<p>Welcome to the admin dashboard. Here is a summary of your application.</p>
<div class="row mb-4">
<div class="col-md-6">
<div class="card text-white bg-primary">
<div class="card-body">
<h5 class="card-title">Total Users</h5>
<p class="card-text fs-2"><?php echo $total_users; ?></p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card text-white bg-success">
<div class="card-body">
<h5 class="card-title">Total Pages</h5>
<p class="card-text fs-2"><?php echo $total_pages; ?></p>
</div>
</div>
</div>
</div>
<div class="row mb-4">
<div class="col">
<a href="users.php" class="btn btn-secondary">Manage Users</a>
<a href="pages.php" class="btn btn-secondary">Manage Pages</a>
<a href="settings.php" class="btn btn-secondary">Settings</a>
</div>
</div>
<div class="card">
<div class="card-header">
Recent Pages
</div>
<div class="card-body">
<?php if (empty($recent_pages)): ?>
<p>No pages created yet.</p>
<?php else: ?>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Slug</th>
<th>Created At</th>
</tr>
</thead>
<tbody>
<?php foreach ($recent_pages as $page): ?>
<tr>
<td><?php echo htmlspecialchars($page['id']); ?></td>
<td><?php echo htmlspecialchars($page['title']); ?></td>
<td><?php echo htmlspecialchars($page['slug']); ?></td>
<td><?php echo htmlspecialchars($page['created_at']); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?php
require_once __DIR__ . '/partials/footer.php';
?>

52
admin/login.php Normal file
View File

@ -0,0 +1,52 @@
<?php
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/partials/header.php';
$error_message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
if (empty($username) || empty($password)) {
$error_message = 'Please enter both username and password.';
} else {
$pdo = db();
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['role'] = $user['role'];
header('Location: index.php');
exit();
} else {
$error_message = 'Invalid username or password.';
}
}
}
?>
<div class="login-container">
<form method="POST" action="login.php">
<h2 style="text-align: center; margin-bottom: 2rem;">Admin Login</h2>
<?php if ($error_message): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error_message); ?></div>
<?php endif; ?>
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" name="username" class="form-control" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary" style="width: 100%;">Login</button>
</form>
</div>
<?php
require_once __DIR__ . '/partials/footer.php';
?>

6
admin/logout.php Normal file
View File

@ -0,0 +1,6 @@
<?php
session_start();
session_unset();
session_destroy();
header('Location: login.php');
exit();

131
admin/pages.php Normal file
View File

@ -0,0 +1,131 @@
<?php
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/partials/header.php';
// Handle form submission for creating a new page
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['create_page'])) {
$title = trim($_POST['title']);
$slug = trim($_POST['slug']);
$content = trim($_POST['content']);
$is_published = isset($_POST['is_published']) ? 1 : 0;
$menu_order = (int)($_POST['menu_order'] ?? 0);
if (empty($title) || empty($slug)) {
$error = "Title and slug are required.";
} else {
// Check if slug already exists
$stmt = db()->prepare("SELECT id FROM pages WHERE slug = ?");
$stmt->execute([$slug]);
if ($stmt->fetch()) {
$error = "Slug already exists. Please choose a unique one.";
} else {
$stmt = db()->prepare("INSERT INTO pages (title, slug, content, is_published, menu_order) VALUES (?, ?, ?, ?, ?)");
if ($stmt->execute([$title, $slug, $content, $is_published, $menu_order])) {
$success = "Page created successfully!";
} else {
$error = "Failed to create page.";
}
}
}
}
// Handle page deletion
if (isset($_GET['delete'])) {
$id = $_GET['delete'];
$stmt = db()->prepare("DELETE FROM pages WHERE id = ?");
if ($stmt->execute([$id])) {
$success = "Page deleted successfully!";
} else {
$error = "Failed to delete page.";
}
}
// Fetch all pages
$stmt = db()->query("SELECT * FROM pages ORDER BY menu_order ASC");
$pages = $stmt->fetchAll();
?>
<div class="container">
<h1>Manage Pages</h1>
<?php if (isset($error)): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
<?php endif; ?>
<?php if (isset($success)): ?>
<div class="alert alert-success"><?php echo htmlspecialchars($success); ?></div>
<?php endif; ?>
<div class="card">
<div class="card-header">
<h2>Create New Page</h2>
</div>
<div class="card-body">
<form action="pages.php" method="POST">
<div class="form-group">
<label for="title">Title</label>
<input type="text" id="title" name="title" class="form-control" required>
</div>
<div class="form-group">
<label for="slug">Slug</label>
<input type="text" id="slug" name="slug" class="form-control" required>
<small>The slug is the URL-friendly version of the name. E.g., "about-us"</small>
</div>
<div class="form-group">
<label for="content">Content</label>
<textarea id="content" name="content" class="form-control" rows="5"></textarea>
</div>
<div class="form-group">
<label for="menu_order">Menu Order</label>
<input type="number" id="menu_order" name="menu_order" class="form-control" value="0">
</div>
<div class="form-check">
<input type="checkbox" id="is_published" name="is_published" class="form-check-input" value="1">
<label for="is_published" class="form-check-label">Publish?</label>
</div>
<button type="submit" name="create_page" class="btn btn-primary mt-3">Create Page</button>
</form>
</div>
</div>
<div class="card mt-4">
<div class="card-header">
<h2>Existing Pages</h2>
</div>
<div class="card-body">
<table class="table">
<thead>
<tr>
<th>Order</th>
<th>Title</th>
<th>Slug</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($pages)): ?>
<tr>
<td colspan="5">No pages found.</td>
</tr>
<?php else: ?>
<?php foreach ($pages as $page): ?>
<tr>
<td><?php echo htmlspecialchars($page['menu_order']); ?></td>
<td><?php echo htmlspecialchars($page['title']); ?></td>
<td>/<?php echo htmlspecialchars($page['slug']); ?></td>
<td><?php echo $page['is_published'] ? '<span class="badge badge-success">Published</span>' : '<span class="badge badge-secondary">Draft</span>'; ?></td>
<td>
<a href="edit_page.php?id=<?php echo $page['id']; ?>" class="btn btn-sm btn-secondary">Edit</a>
<a href="pages.php?delete=<?php echo $page['id']; ?>" class="btn btn-sm btn-danger" onclick="return confirm('Are you sure you want to delete this page?');">Delete</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php require_once __DIR__ . '/partials/footer.php'; ?>

View File

@ -0,0 +1,7 @@
<?php if (isset($_SESSION['user_id'])): ?>
</div> <!-- .main-content -->
<?php endif; ?>
</body>
</html>

46
admin/partials/header.php Normal file
View File

@ -0,0 +1,46 @@
<?php
session_start();
// Protect admin pages
if (basename($_SERVER['PHP_SELF']) != 'login.php') {
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit();
}
}
$current_page = basename($_SERVER['PHP_SELF']);
// Fetch site title from settings
require_once __DIR__ . '/../../db/config.php';
$pdo = db();
$stmt = $pdo->query("SELECT setting_value FROM `settings` WHERE setting_key = 'site_title'");
$site_title = $stmt->fetchColumn();
if (!$site_title) {
$site_title = 'Admin Panel';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($site_title); ?></title>
<link rel="stylesheet" href="style.css?v=<?php echo time(); ?>">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<?php if (isset($_SESSION['user_id'])): ?>
<div class="sidebar">
<a href="index.php" class="<?php echo ($current_page == 'index.php') ? 'active' : ''; ?>">Dashboard</a>
<a href="users.php" class="<?php echo ($current_page == 'users.php') ? 'active' : ''; ?>">User Management</a>
<a href="analytics.php" class="<?php echo ($current_page == 'analytics.php') ? 'active' : ''; ?>">Analytics</a>
<a href="pages.php" class="<?php echo ($current_page == 'pages.php' || $current_page == 'edit_page.php') ? 'active' : ''; ?>">Pages</a>
<a href="settings.php" class="<?php echo ($current_page == 'settings.php') ? 'active' : ''; ?>">Settings</a>
<a href="logout.php">Logout</a>
</div>
<div class="main-content">
<?php endif; ?>

86
admin/settings.php Normal file
View File

@ -0,0 +1,86 @@
<?php
require_once __DIR__ . '/partials/header.php';
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$site_title = $_POST['site_title'] ?? '';
$responses_per_page = $_POST['responses_per_page'] ?? '10';
$contact_email = $_POST['contact_email'] ?? '';
$pdo = db();
$stmt = $pdo->prepare("INSERT INTO `settings` (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)");
$stmt->execute(['site_title', $site_title]);
$stmt->execute(['responses_per_page', $responses_per_page]);
$stmt->execute(['contact_email', $contact_email]);
$success_message = 'Settings saved successfully!';
}
// Fetch current settings
$pdo = db();
$stmt = $pdo->query("SELECT * FROM `settings`");
$settings = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
$site_title = $settings['site_title'] ?? 'My Awesome App';
$responses_per_page = $settings['responses_per_page'] ?? '10';
$contact_email = $settings['contact_email'] ?? '';
?>
<div class="container-fluid">
<div class="d-sm-flex justify-content-between align-items-center mb-4">
<h3 class="text-dark mb-0">Settings</h3>
</div>
<?php if (isset($success_message)): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<?php echo $success_message; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<div class="row">
<div class="col">
<div class="card shadow mb-3">
<div class="card-header py-3">
<p class="text-primary m-0 fw-bold">Application Settings</p>
</div>
<div class="card-body">
<form method="POST">
<div class="row">
<div class="col">
<div class="mb-3">
<label class="form-label" for="site_title"><strong>Site Title</strong></label>
<input class="form-control" type="text" id="site_title" value="<?php echo htmlspecialchars($site_title); ?>" name="site_title">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="mb-3">
<label class="form-label" for="responses_per_page"><strong>Responses Per Page</strong></label>
<input class="form-control" type="number" id="responses_per_page" value="<?php echo htmlspecialchars($responses_per_page); ?>" name="responses_per_page">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="mb-3">
<label class="form-label" for="contact_email"><strong>Contact Email</strong></label>
<input class="form-control" type="email" id="contact_email" value="<?php echo htmlspecialchars($contact_email); ?>" name="contact_email">
</div>
</div>
</div>
<div class="mb-3">
<button class="btn btn-primary btn-sm" type="submit">Save Settings</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<?php
require_once __DIR__ . '/partials/footer.php';
?>

144
admin/style.css Normal file
View File

@ -0,0 +1,144 @@
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background-color: #F9FAFB;
color: #111827;
margin: 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
.login-container {
max-width: 400px;
margin: 4rem auto;
padding: 2rem;
background-color: #FFFFFF;
border-radius: 0.5rem;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
}
h1, h2, h3, h4, h5, h6 {
color: #111827;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-control {
width: 100%;
padding: 0.75rem 1rem;
border: 1px solid #D1D5DB;
border-radius: 0.375rem;
box-sizing: border-box;
}
.btn {
display: inline-block;
padding: 0.75rem 1.5rem;
border: none;
border-radius: 0.375rem;
font-weight: 600;
cursor: pointer;
text-decoration: none;
}
.btn-primary {
background-color: #4F46E5;
color: #FFFFFF;
}
.alert {
padding: 1rem;
margin-bottom: 1rem;
border-radius: 0.375rem;
}
.alert-danger {
background-color: #FEE2E2;
color: #B91C1C;
}
.header {
background-color: #FFFFFF;
padding: 1rem 2rem;
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
display: flex;
justify-content: space-between;
align-items: center;
}
.header .logo {
font-size: 1.5rem;
font-weight: 700;
}
.header a {
text-decoration: none;
color: #111827;
}
.sidebar {
width: 250px;
background-color: #1F2937;
color: #F9FAFB;
height: 100vh;
position: fixed;
padding-top: 1rem;
}
.sidebar a {
display: block;
padding: 1rem 1.5rem;
color: #D1D5DB;
text-decoration: none;
font-weight: 500;
}
.sidebar a:hover, .sidebar a.active {
background-color: #374151;
color: #FFFFFF;
}
.main-content {
margin-left: 250px;
padding: 2rem;
}
.card {
background-color: #FFFFFF;
border-radius: 0.5rem;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
margin-bottom: 2rem;
}
.card-header {
padding: 1.5rem;
border-bottom: 1px solid #E5E7EB;
font-size: 1.25rem;
font-weight: 600;
}
.card-body {
padding: 1.5rem;
}
.table {
width: 100%;
border-collapse: collapse;
}
.table th, .table td {
padding: 1rem;
text-align: left;
border-bottom: 1px solid #E5E7EB;
}
.table th {
font-weight: 600;
background-color: #F9FAFB;
}

175
admin/users.php Normal file
View File

@ -0,0 +1,175 @@
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
require_once '../db/config.php';
// Handle Delete User
if (isset($_GET['delete_id'])) {
$delete_id = $_GET['delete_id'];
try {
$pdo = db();
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
$stmt->execute([$delete_id]);
header("Location: users.php?deleted=true");
exit;
} catch (PDOException $e) {
$error_message = "Error deleting user: " . $e->getMessage();
}
}
// Handle Add User Form Submission
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['username'])) {
$username = trim($_POST['username']);
$password = $_POST['password'];
$role = $_POST['role'];
if (!empty($username) && !empty($password) && !empty($role)) {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
try {
$pdo = db();
$stmt = $pdo->prepare("INSERT INTO users (username, password, role) VALUES (?, ?, ?)");
$stmt->execute([$username, $hashed_password, $role]);
// Redirect to avoid form resubmission
header("Location: users.php");
exit;
} catch (PDOException $e) {
// Check for duplicate entry
if ($e->errorInfo[1] == 1062) {
$error_message = "Error: This username is already taken.";
} else {
$error_message = "Database error: " . $e->getMessage();
}
}
} else {
$error_message = "All fields are required.";
}
}
// Fetch all users
try {
$pdo = db();
$stmt = $pdo->query('SELECT id, username, role, created_at FROM users ORDER BY created_at DESC');
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
// For now, we'll just die on error. In a real app, handle this gracefully.
die("Error fetching users: " . $e->getMessage());
}
$page_title = "User Management";
include 'partials/header.php';
?>
<div class="container-fluid">
<?php if (!empty($error_message)): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<?php echo $error_message; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<div class="d-sm-flex justify-content-between align-items-center mb-4">
<h3 class="text-dark mb-0">User Management</h3>
<a class="btn btn-primary btn-sm d-none d-sm-inline-block" role="button" href="#addUserModal" data-bs-toggle="modal">
<i class="fas fa-plus fa-sm text-white-50"></i>&nbsp;Add New User
</a>
</div>
<?php if (isset($_GET['deleted'])): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
User successfully deleted.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php if (isset($_GET['updated'])): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
User successfully updated.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<div class="card shadow">
<div class="card-header py-3">
<p class="text-primary m-0 fw-bold">Registered Users</p>
</div>
<div class="card-body">
<div class="table-responsive table mt-2" id="dataTable" role="grid" aria-describedby="dataTable_info">
<table class="table my-0" id="dataTable">
<thead>
<tr>
<th>Username</th>
<th>Role</th>
<th>Registered On</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($users)): ?>
<tr>
<td colspan="4" class="text-center">No users found.</td>
</tr>
<?php else: ?>
<?php foreach ($users as $user): ?>
<tr>
<td><?php echo htmlspecialchars($user['username']); ?></td>
<td><?php echo htmlspecialchars(ucfirst($user['role'])); ?></td>
<td><?php echo date("F j, Y, g:i a", strtotime($user['created_at'])); ?></td>
<td>
<a href="edit_user.php?id=<?php echo $user['id']; ?>" class="btn btn-sm btn-warning me-2" title="Edit"><i class="fas fa-pencil-alt"></i></a>
<a href="users.php?delete_id=<?php echo $user['id']; ?>" class="btn btn-sm btn-danger" title="Delete" onclick="return confirm('Are you sure you want to delete this user?');"><i class="fas fa-trash"></i></a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Add User Modal -->
<div class="modal fade" id="addUserModal" tabindex="-1" aria-labelledby="addUserModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addUserModalLabel">Add New User</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="addUserForm" action="users.php" method="POST">
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div class="mb-3">
<label for="role" class="form-label">Role</label>
<select class="form-select" id="role" name="role">
<option value="admin">Admin</option>
<option value="editor">Editor</option>
</select>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" form="addUserForm" class="btn btn-primary">Save User</button>
</div>
</div>
</div>
</div>
<?php include 'partials/footer.php'; ?>

54
assets/css/custom.css Normal file
View File

@ -0,0 +1,54 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
body {
font-family: 'Inter', sans-serif;
background-color: #F9FAFB;
color: #111827;
}
.hero {
background: linear-gradient(135deg, #4F46E5, #2563EB);
color: white;
}
.btn-primary {
background-color: #4F46E5;
border-color: #4F46E5;
padding: 0.75rem 1.5rem;
border-radius: 0.5rem;
font-weight: 500;
transition: background-color 0.2s ease-in-out;
}
.btn-primary:hover {
background-color: #4338CA;
border-color: #4338CA;
}
.survey-card {
background-color: #FFFFFF;
border-radius: 0.75rem;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
}
.form-label {
font-weight: 600;
margin-bottom: 0.5rem;
}
.form-control, .form-select {
border-radius: 0.5rem;
padding: 0.75rem 1rem;
border: 1px solid #D1D5DB;
}
.form-control:focus, .form-select:focus {
border-color: #4F46E5;
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2);
}
.form-check-input:checked {
background-color: #4F46E5;
border-color: #4F46E5;
}

84
assets/css/style.css Normal file
View File

@ -0,0 +1,84 @@
/* General Body Styling */
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
background-color: #f8f9fa;
color: #333;
}
/* Main Container */
.container {
max-width: 960px;
margin: 2rem auto;
padding: 0 1.5rem;
}
/* Header and Navigation */
header {
background-color: #ffffff;
padding: 1rem 0;
border-bottom: 1px solid #e9ecef;
margin-bottom: 2rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.04);
}
header .container {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 0;
margin-bottom: 0;
}
header .logo {
font-size: 1.5rem;
font-weight: bold;
text-decoration: none;
color: #333;
}
header nav ul {
margin: 0;
padding: 0;
list-style: none;
display: flex;
gap: 1.5rem;
}
header nav a {
text-decoration: none;
color: #555;
font-weight: 500;
transition: color 0.2s ease-in-out;
}
header nav a:hover,
header nav a.active {
color: #007bff;
}
/* Page Content */
main {
background-color: #ffffff;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.04);
}
h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
color: #212529;
}
/* Footer */
footer {
text-align: center;
margin-top: 3rem;
padding: 1.5rem 0;
color: #6c757d;
font-size: 0.9rem;
border-top: 1px solid #e9ecef;
}

53
assets/js/main.js Normal file
View File

@ -0,0 +1,53 @@
document.addEventListener('DOMContentLoaded', function () {
const surveyForm = document.getElementById('surveyForm');
const formMessages = document.getElementById('form-messages');
if (surveyForm) {
surveyForm.addEventListener('submit', function (e) {
e.preventDefault();
// --- Client-side validation ---
const satisfaction = surveyForm.querySelector('input[name="satisfaction"]:checked');
if (!satisfaction) {
displayMessage('Please select a satisfaction level.', 'danger');
return;
}
const formData = new FormData(surveyForm);
const submitButton = surveyForm.querySelector('button[type="submit"]');
submitButton.disabled = true;
submitButton.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Submitting...';
fetch('submit.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
displayMessage(data.message, 'success');
// Redirect to thank-you page after a short delay
setTimeout(() => {
window.location.href = 'thank-you.php';
}, 1500);
} else {
displayMessage(data.message || 'An unexpected error occurred.', 'danger');
submitButton.disabled = false;
submitButton.textContent = 'Submit Feedback';
}
})
.catch(error => {
console.error('Error:', error);
displayMessage('A network error occurred. Please try again.', 'danger');
submitButton.disabled = false;
submitButton.textContent = 'Submit Feedback';
});
});
}
function displayMessage(message, type) {
if (formMessages) {
formMessages.innerHTML = `<div class="alert alert-${type}" role="alert">${message}</div>`;
}
}
});

View File

@ -6,12 +6,33 @@ define('DB_USER', 'app_30953');
define('DB_PASS', 'e45f2778-db1f-450c-99c6-29efb4601472'); define('DB_PASS', 'e45f2778-db1f-450c-99c6-29efb4601472');
function db() { function db() {
static $pdo; static $pdo;
if (!$pdo) { if (!$pdo) {
$pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [ $pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8mb4', DB_USER, DB_PASS, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]); ]);
} }
return $pdo; return $pdo;
} }
function run_migrations() {
$pdo = db();
$pdo->exec("CREATE TABLE IF NOT EXISTS `migrations` (`migration` VARCHAR(255) PRIMARY KEY, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP)");
$stmt = $pdo->query("SELECT `migration` FROM `migrations`");
$run_migrations = $stmt->fetchAll(PDO::FETCH_COLUMN);
$migration_files = glob(__DIR__ . '/migrations/*.sql');
foreach ($migration_files as $file) {
$migration_name = basename($file);
if (!in_array($migration_name, $run_migrations)) {
$sql = file_get_contents($file);
$pdo->exec($sql);
$stmt = $pdo->prepare("INSERT INTO `migrations` (`migration`) VALUES (?)");
$stmt->execute([$migration_name]);
}
}
}
run_migrations();

View File

@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS `users` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(255) NOT NULL UNIQUE,
`password` VARCHAR(255) NOT NULL,
`role` VARCHAR(50) NOT NULL DEFAULT 'admin',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -0,0 +1,15 @@
-- Create settings table
CREATE TABLE IF NOT EXISTS `settings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`setting_key` varchar(255) NOT NULL,
`setting_value` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `setting_key` (`setting_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Insert default settings
INSERT INTO `settings` (`setting_key`, `setting_value`) VALUES
('site_title', 'My Awesome App'),
('responses_per_page', '10'),
('contact_email', 'admin@example.com')
ON DUPLICATE KEY UPDATE `setting_key` = `setting_key`;

View File

@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS pages (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
slug VARCHAR(255) NOT NULL UNIQUE,
content TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

View File

@ -0,0 +1,3 @@
ALTER TABLE `pages`
ADD COLUMN `is_published` TINYINT(1) NOT NULL DEFAULT 0,
ADD COLUMN `menu_order` INT(11) NOT NULL DEFAULT 0;

10
includes/footer.php Normal file
View File

@ -0,0 +1,10 @@
</main>
</div>
<footer>
<div class="container">
<p>&copy; <?php echo date('Y'); ?> <?php echo htmlspecialchars($site_title); ?>. All Rights Reserved.</p>
</div>
</footer>
<script src="/assets/js/main.js?v=<?php echo time(); ?>"></script>
</body>
</html>

44
includes/header.php Normal file
View File

@ -0,0 +1,44 @@
<?php
require_once __DIR__ . '/../db/config.php';
// Fetch site title from settings
$stmt = db()->query("SELECT value FROM settings WHERE name = 'site_title'");
$site_title_setting = $stmt->fetchColumn();
$site_title = $site_title_setting ?: 'My Awesome Website';
// Fetch pages for navigation
$pages_stmt = db()->query("SELECT title, slug FROM pages WHERE is_published = 1 ORDER BY menu_order ASC");
$nav_pages = $pages_stmt->fetchAll(PDO::FETCH_ASSOC);
$current_slug = basename($_SERVER['REQUEST_URI']);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo isset($page_title) ? htmlspecialchars($page_title) . ' | ' . htmlspecialchars($site_title) : htmlspecialchars($site_title); ?></title>
<meta name="description" content="<?php echo isset($meta_description) ? htmlspecialchars($meta_description) : 'Welcome to our website'; ?>">
<link rel="stylesheet" href="/assets/css/style.css?v=<?php echo time(); ?>">
</head>
<body>
<header>
<div class="container">
<a href="/" class="logo"><?php echo htmlspecialchars($site_title); ?></a>
<nav>
<ul>
<li><a href="/" class="<?php echo ($current_slug == 'index.php' || $current_slug == '') ? 'active' : ''; ?>">Home</a></li>
<?php foreach ($nav_pages as $p): ?>
<li>
<a href="/page.php?slug=<?php echo htmlspecialchars($p['slug']); ?>"
class="<?php echo (isset($_GET['slug']) && $_GET['slug'] == $p['slug']) ? 'active' : ''; ?>">
<?php echo htmlspecialchars($p['title']); ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</nav>
</div>
</header>
<div class="container">
<main>

211
index.php
View File

@ -1,150 +1,77 @@
<?php <?php
declare(strict_types=1); require_once 'db/config.php';
@ini_set('display_errors', '1');
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
$phpVersion = PHP_VERSION; // Fetch settings
$now = date('Y-m-d H:i:s'); $settings_stmt = db()->query("SELECT * FROM settings");
$settings = $settings_stmt->fetchAll(PDO::FETCH_KEY_PAIR);
$site_title = $settings['site_title'] ?? 'Survey App';
// Fetch total responses
$responses_stmt = db()->query("SELECT COUNT(*) FROM survey_responses");
$total_responses = $responses_stmt->fetchColumn();
?> ?>
<!doctype html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Style</title> <title><?php echo htmlspecialchars($site_title); ?> - Create & Share Surveys</title>
<?php <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
// Read project preview data from environment <link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? ''; <meta name="description" content="Create and share surveys effortlessly. Gather feedback, analyze results, and make better decisions.">
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; <meta name="keywords" content="survey, feedback, questionnaire, form builder, online survey, poll, data collection, research, customer feedback, employee engagement, market research, Built with Flatlogic Generator">
?> <meta property="og:title" content="<?php echo htmlspecialchars($site_title); ?>">
<?php if ($projectDescription): ?> <meta property="og:description" content="Built with Flatlogic Generator">
<!-- Meta description --> <meta property="og:image" content="">
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' /> <meta name="twitter:card" content="summary_large_image">
<!-- Open Graph meta tags --> <meta name="twitter:image" content="">
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<!-- Twitter meta tags -->
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<?php endif; ?>
<?php if ($projectImageUrl): ?>
<!-- Open Graph image -->
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<!-- Twitter image -->
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<?php endif; ?>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-color-start: #6a11cb;
--bg-color-end: #2575fc;
--text-color: #ffffff;
--card-bg-color: rgba(255, 255, 255, 0.01);
--card-border-color: rgba(255, 255, 255, 0.1);
}
body {
margin: 0;
font-family: 'Inter', sans-serif;
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
text-align: center;
overflow: hidden;
position: relative;
}
body::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
animation: bg-pan 20s linear infinite;
z-index: -1;
}
@keyframes bg-pan {
0% { background-position: 0% 0%; }
100% { background-position: 100% 100%; }
}
main {
padding: 2rem;
}
.card {
background: var(--card-bg-color);
border: 1px solid var(--card-border-color);
border-radius: 16px;
padding: 2rem;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
}
.loader {
margin: 1.25rem auto 1.25rem;
width: 48px;
height: 48px;
border: 3px solid rgba(255, 255, 255, 0.25);
border-top-color: #fff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.hint {
opacity: 0.9;
}
.sr-only {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap; border: 0;
}
h1 {
font-size: 3rem;
font-weight: 700;
margin: 0 0 1rem;
letter-spacing: -1px;
}
p {
margin: 0.5rem 0;
font-size: 1.1rem;
}
code {
background: rgba(0,0,0,0.2);
padding: 2px 6px;
border-radius: 4px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
footer {
position: absolute;
bottom: 1rem;
font-size: 0.8rem;
opacity: 0.7;
}
</style>
</head> </head>
<body> <body class="bg-light">
<main>
<div class="card"> <div class="hero text-center py-5 bg-white">
<h1>Analyzing your requirements and generating your website…</h1> <div class="container py-5">
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes"> <h1 class="display-4 fw-bold"><?php echo htmlspecialchars($site_title); ?></h1>
<span class="sr-only">Loading…</span> <p class="lead col-lg-8 mx-auto">
</div> Build beautiful, intuitive surveys in minutes. Gather feedback, analyze data, and gain insights to drive your business forward.
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p> </p>
<p class="hint">This page will update automatically as the plan is implemented.</p> <a href="survey.php" class="btn btn-primary btn-lg mt-4">Take a Sample Survey</a>
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p> </div>
</div> </div>
</main>
<footer> <div class="container py-5">
Page updated: <?= htmlspecialchars($now) ?> (UTC) <div class="row text-center">
</footer> <div class="col-lg-4 mb-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-body p-4">
<h3 class="h4">Easy to Use</h3>
<p>An intuitive interface makes survey creation a breeze.</p>
</div>
</div>
</div>
<div class="col-lg-4 mb-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-body p-4">
<h3 class="h4">Powerful Insights</h3>
<p>Analyze responses with real-time charts and data exports.</p>
</div>
</div>
</div>
<div class="col-lg-4 mb-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-body p-4">
<h3 class="h4">Total Responses</h3>
<p class="display-6 fw-bold"><?php echo $total_responses; ?></p>
</div>
</div>
</div>
</div>
</div>
<footer class="text-center py-4 text-muted">
<p>&copy; <?php echo date("Y"); ?> <?php echo htmlspecialchars($site_title); ?>. All rights reserved. | <a href="/admin">Admin Login</a></p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body> </body>
</html> </html>

41
page.php Normal file
View File

@ -0,0 +1,41 @@
<?php
require_once __DIR__ . '/db/config.php';
$slug = $_GET['slug'] ?? null;
if (!$slug) {
http_response_code(404);
echo "Page not found.";
exit();
}
$stmt = db()->prepare("SELECT * FROM pages WHERE slug = ?");
$stmt->execute([$slug]);
$page = $stmt->fetch();
if (!$page) {
http_response_code(404);
// You can create a more sophisticated 404 page
include 'includes/header.php';
echo "<div class=\"container\"><p>Sorry, the page you are looking for does not exist.</p></div>";
include 'includes/footer.php';
exit();
}
// SEO and page metadata
$page_title = htmlspecialchars($page['title']);
$meta_description = htmlspecialchars(substr(strip_tags($page['content']), 0, 160));
include 'includes/header.php';
?>
<div class="container page-content">
<h1><?php echo htmlspecialchars($page['title']); ?></h1>
<hr>
<div>
<?php echo nl2br(htmlspecialchars($page['content'])); // Using nl2br to respect line breaks, and htmlspecialchars for security ?>
</div>
</div>
<?php
include 'includes/footer.php';

45
submit.php Normal file
View File

@ -0,0 +1,45 @@
<?php
require_once __DIR__ . '/db/config.php';
header('Content-Type: application/json');
$response = ['success' => false, 'message' => 'An unexpected error occurred.'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$satisfaction = filter_input(INPUT_POST, 'satisfaction', FILTER_SANITIZE_STRING);
$comments = filter_input(INPUT_POST, 'comments', FILTER_SANITIZE_STRING);
$how_heard = filter_input(INPUT_POST, 'how_heard', FILTER_SANITIZE_STRING);
if (empty($satisfaction)) {
$response['message'] = 'Satisfaction level is a required field.';
echo json_encode($response);
exit;
}
try {
$pdo = db();
$sql = "INSERT INTO survey_responses (satisfaction, comments, how_heard) VALUES (:satisfaction, :comments, :how_heard)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':satisfaction', $satisfaction);
$stmt->bindParam(':comments', $comments);
$stmt->bindParam(':how_heard', $how_heard);
if ($stmt->execute()) {
$response['success'] = true;
$response['message'] = 'Thank you! Your feedback has been submitted successfully.';
} else {
$response['message'] = 'Failed to save your response. Please try again.';
}
} catch (PDOException $e) {
// In a real app, you'd log this error. For now, send a generic message.
// error_log('PDOException: ' . $e->getMessage());
$response['message'] = 'Database error: Could not save your response.';
}
} else {
$response['message'] = 'Invalid request method.';
}
echo json_encode($response);

88
survey.php Normal file
View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sample Survey - Survey App</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
<meta name="description" content="Built with Flatlogic Generator">
<meta name="keywords" content="survey, feedback, questionnaire, form builder, online survey, poll, data collection, research, customer feedback, employee engagement, market research, Built with Flatlogic Generator">
<meta property="og:title" content="clone surveymonkey software">
<meta property="og:description" content="Built with Flatlogic Generator">
<meta property="og:image" content="">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="">
</head>
<body>
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="text-center mb-5">
<h1 class="display-5 fw-bold">Customer Feedback Survey</h1>
<p class="lead text-muted">We value your feedback! Please take a moment to share your thoughts.</p>
</div>
<div class="survey-card p-4 p-md-5">
<form action="submit.php" method="POST" id="surveyForm">
<!-- Question 1: Multiple Choice -->
<div class="mb-5">
<label class="form-label">1. How satisfied are you with our product?</label>
<div class="form-check">
<input class="form-check-input" type="radio" name="satisfaction" id="verySatisfied" value="very_satisfied" required>
<label class="form-check-label" for="verySatisfied">Very Satisfied</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="satisfaction" id="satisfied" value="satisfied">
<label class="form-check-label" for="satisfied">Satisfied</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="satisfaction" id="neutral" value="neutral">
<label class="form-check-label" for="neutral">Neutral</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="satisfaction" id="unsatisfied" value="unsatisfied">
<label class="form-check-label" for="unsatisfied">Unsatisfied</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="satisfaction" id="veryUnsatisfied" value="very_unsatisfied">
<label class="form-check-label" for="veryUnsatisfied">Very Unsatisfied</label>
</div>
</div>
<!-- Question 2: Text Area -->
<div class="mb-5">
<label for="comments" class="form-label">2. Do you have any comments or suggestions?</label>
<textarea class="form-control" id="comments" name="comments" rows="5" placeholder="Your feedback helps us improve..."></textarea>
</div>
<!-- Question 3: Select -->
<div class="mb-5">
<label for="howHeard" class="form-label">3. How did you hear about us?</label>
<select class="form-select" id="howHeard" name="how_heard">
<option selected disabled value="">Choose an option...</option>
<option value="social_media">Social Media</option>
<option value="friend">From a friend</option>
<option value="search_engine">Search Engine (Google, etc.)</option>
<option value="advertisement">Advertisement</option>
<option value="other">Other</option>
</select>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary btn-lg">Submit Feedback</button>
</div>
</form>
<div id="form-messages" class="mt-3"></div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
</body>
</html>

36
thank-you.php Normal file
View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="refresh" content="5;url=index.php">
<title>Thank You - Survey App</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
<meta name="description" content="Built with Flatlogic Generator">
<meta name="keywords" content="survey, feedback, questionnaire, form builder, online survey, poll, data collection, research, customer feedback, employee engagement, market research, Built with Flatlogic Generator">
<meta property="og:title" content="clone surveymonkey software">
<meta property="og:description" content="Built with Flatlogic Generator">
<meta property="og:image" content="">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="">
</head>
<body>
<div class="container d-flex flex-column justify-content-center align-items-center vh-100">
<div class="text-center survey-card p-5">
<svg xmlns="http://www.w3.org/2000/svg" class="text-success mb-4" width="80" height="80" fill="currentColor" class="bi bi-check-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</svg>
<h1 class="display-4">Thank You!</h1>
<p class="lead">Your submission has been received.</p>
<hr class="my-4">
<p>You can now safely close this page.</p>
<a class="btn btn-primary btn-lg mt-3" href="index.php" role="button">Back to Home</a>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>