Made pages edit better and added messages

This commit is contained in:
Nick Yeoman 2025-08-14 18:14:59 -07:00
parent 2f76c1ae35
commit 892110703b
16 changed files with 385 additions and 77 deletions

View File

@ -19,9 +19,24 @@ $framework_routes = [
'/novaconium/page/edit/{id}' => [ '/novaconium/page/edit/{id}' => [
'get' => 'NOVACONIUM/editpage' 'get' => 'NOVACONIUM/editpage'
], ],
'/novaconium/page/create' => [
'get' => 'NOVACONIUM/editpage'
],
'/novaconium/savePage' => [ '/novaconium/savePage' => [
'post' => 'NOVACONIUM/savepage' 'post' => 'NOVACONIUM/savepage'
], ],
'/novaconium/messages' => [
'get' => 'NOVACONIUM/messages'
],
'/novaconium/messages/delete/{id}' => [
'get' => 'NOVACONIUM/message_delete'
],
'/novaconium/messages/edit/{id}' => [
'get' => 'NOVACONIUM/message_edit'
],
'/novaconium/message_save' => [
'post' => 'NOVACONIUM/message_save'
],
'/novaconium/logout' => [ '/novaconium/logout' => [
'post' => 'NOVACONIUM/logout', 'post' => 'NOVACONIUM/logout',
'get' => 'NOVACONIUM/logout' 'get' => 'NOVACONIUM/logout'

View File

@ -1,5 +1,8 @@
<?php <?php
$data['title'] = 'Novaconium Dashboard Page'; $data = array_merge($data, [
'title' => 'Novaconium Dashboard Page',
'pageclass' => 'novaconium'
]);
if ( empty($session->get('username'))) { if ( empty($session->get('username'))) {
$redirect->url('/novaconium/login'); $redirect->url('/novaconium/login');

View File

@ -1,30 +1,73 @@
<?php <?php
$data['title'] = 'Novaconium Edit Page';
if ( empty($session->get('username'))) { $data = array_merge($data, [
'title' => 'Novaconium Edit Page',
'pageclass' => 'novaconium'
]);
// Check if logged in
if (empty($session->get('username'))) {
$messages->error('You are not logged in');
$redirect->url('/novaconium/login'); $redirect->url('/novaconium/login');
$messages->error('You are not loggedin');
makeitso(); makeitso();
} }
$pageid = $router->parameters['id']; // Get page ID from router parameters
$query=<<<EOSQL $pageid = $router->parameters['id'] ?? null;
SELECT
id, if (!empty($pageid)) {
title, // Existing page: fetch from database
intro, $query = <<<EOSQL
slug, SELECT
body, id,
draft, title,
created, heading,
updated description,
FROM pages keywords,
WHERE id = '$pageid' author,
slug,
path,
intro,
body,
notes,
draft,
changefreq,
priority,
created,
updated
FROM pages
WHERE id = ?
EOSQL; EOSQL;
$data['rows'] = $db->getRow($query); $data['rows'] = $db->getRow($query, [$pageid]);
$data = array_merge($data, [
'tinymce' => true, // If no row is found, treat as new page
'pageid' => 'admin-edit-page' if (!$data['rows']) {
]); $pageid = null;
view('@novacore/editpage', $data); }
}
if (empty($pageid)) {
// New page: set default values for all fields
$data['rows'] = [
'id' => '',
'title' => '',
'heading' => '',
'description' => '',
'keywords' => '',
'author' => $session->get('username') ?? '',
'slug' => '',
'path' => '',
'intro' => '',
'body' => '',
'notes' => '',
'draft' => 0,
'changefreq' => 'monthly',
'priority' => 0.0,
'created' => date('Y-m-d H:i:s'),
'updated' => date('Y-m-d H:i:s')
];
}
// Render the edit page view
view('@novacore/editpage', $data);

View File

@ -0,0 +1,15 @@
<?php
if ( empty($session->get('username'))) {
$redirect->url('/novaconium/login');
$messages->error('You are not loggedin');
makeitso();
}
$messageid = $router->parameters['id'];
$query="DELETE FROM contactForm WHERE `contactForm`.`id` = ?";
$db->query($query, [$messageid]);
$redirect->url('/novaconium/messages');
$messages->notice("Removed Message $messageid");
makeitso();

View File

@ -0,0 +1,19 @@
<?php
$data = array_merge($data, [
'title' => 'Novaconium Message Page',
'pageclass' => 'novaconium'
]);
if ( empty($session->get('username'))) {
$redirect->url('/novaconium/login');
$messages->error('You are not loggedin');
makeitso();
}
$messageid = $router->parameters['id'];
$query = "SELECT id, name, email, message, created, unread FROM contactForm WHERE id = '$messageid'";
$data['themessage'] = $db->getRow($query);
view('@novacore/editmessage', $data);

View File

@ -0,0 +1,57 @@
<?php
use Nickyeoman\Validation;
$v = new Nickyeoman\Validation\Validate();
$url_success = '/novaconium/messages';
$url_error = '/novaconium/messages/edit/' . $post->get('id'); // Redirect back to the message edit form on error
// Check if logged in
if (empty($session->get('username'))) {
$messages->error('You are not logged in');
$redirect->url('/novaconium/login');
makeitso();
}
// Check CSRF token
if ($session->get('token') != $post->get('token')) {
$messages->error('Invalid token');
$redirect->url($url_success);
makeitso();
}
// Get POST data
$id = $post->get('id');
$name = $post->get('name');
$email = $post->get('email');
$message = $post->get('message');
$unread = !empty($post->get('unread')) ? 1 : 0;
// Validate required fields
if (empty($id) || empty($message) || empty($email)) {
$messages->error('One of the required fields was empty.');
$redirect->url($url_error);
makeitso();
}
try {
// Prepare update query
$query = "UPDATE `contactForm`
SET `name` = ?, `email` = ?, `message` = ?, `unread` = ?
WHERE `id` = ?";
$params = [$name, $email, $message, $unread, $id];
$db->query($query, $params);
$messages->notice('Message updated successfully');
} catch (Exception $e) {
$messages->error('Error updating message: ' . $e->getMessage());
$redirect->url($url_error);
makeitso();
}
// Redirect to success page
$redirect->url($url_success);

21
controllers/messages.php Normal file
View File

@ -0,0 +1,21 @@
<?php
$data = array_merge($data, [
'title' => 'Novaconium Messages',
'pageclass' => 'novaconium'
]);
if ( empty($session->get('username'))) {
$redirect->url('/novaconium/login');
$messages->error('You are not loggedin');
makeitso();
}
// Get the pages
$query = "SELECT id, name, email, LEFT(message, 40) AS message, created, unread FROM contactForm";
$matched = $db->getRows($query);
$data['messages'] = $matched;
view('@novacore/messages', $data);

View File

@ -1,5 +1,9 @@
<?php <?php
$data['title'] = 'Novaconium Pages';
$data = array_merge($data, [
'title' => 'Novaconium Pages',
'pageclass' => 'novaconium'
]);
if ( empty($session->get('username'))) { if ( empty($session->get('username'))) {
$redirect->url('/novaconium/login'); $redirect->url('/novaconium/login');

View File

@ -3,53 +3,81 @@
use Nickyeoman\Validation; use Nickyeoman\Validation;
$v = new Nickyeoman\Validation\Validate(); $v = new Nickyeoman\Validation\Validate();
$url_success = '/dashboard'; $url_error = '/novaconium/page/edit/' . $post->get('id'); // fallback for errors
$url_error = '/novaconium/page/edit/' . $post->get('id'); // Redirect back to the page edit form on error
if ( empty($session->get('username'))) { // Check login
if (empty($session->get('username'))) {
$messages->error('You are not logged in');
$redirect->url('/novaconium/login'); $redirect->url('/novaconium/login');
$messages->error('You are not loggedin');
makeitso(); makeitso();
} }
// Check Token // Check token
if ($session->get('token') != $post->get('token')) { if ($session->get('token') != $post->get('token')) {
$redirect->url('/novaconium/pages');
$messages->error('Invalid Token'); $messages->error('Invalid Token');
$redirect->url('/novaconium/pages');
makeitso(); makeitso();
} }
$id = $post->get('id'); // Gather POST data
$slug = $post->get('slug'); $id = $post->get('id');
$title = $_POST['title']; $title = $_POST['title'] ?? '';
$body = $_POST['body']; // We want it dirty $heading = $_POST['heading'] ?? '';
$intro = $_POST['intro']; // We want it dirty $description = $_POST['description'] ?? '';
$keywords = $_POST['keywords'] ?? '';
$author = $_POST['author'] ?? '';
$slug = $_POST['slug'] ?? '';
$path = $_POST['path'] ?? null;
$intro = $_POST['intro'] ?? '';
$body = $_POST['body'] ?? '';
$notes = $_POST['notes'] ?? '';
$draft = !empty($post->get('draft')) ? 1 : 0;
$changefreq = $_POST['changefreq'] ?? 'monthly';
$priority = $_POST['priority'] ?? 0.0;
if ( empty( $post->get('draft') ) ) { // Validate required fields
$draft = 0; if (empty($title) || empty($slug) || empty($body)) {
} else { $messages->error('Title, Slug, and Body are required.');
$draft = 1; $redirect->url($url_error);
}
if ( empty($id) || empty($slug) || empty($body) ) {
$messages->error('One of the fields was empty.');
$redirect->url($url_fail);
makeitso(); makeitso();
} }
try { try {
if (!empty($id)) {
$query = "UPDATE `pages` SET `title` = ?, `slug` = ?, `body` = ?, `intro` = ?, `draft` = ?, `updated` = NOW() WHERE `id` = ?"; // Update existing page
$params = [$title, $slug, $body, $intro, $draft, $id]; $query = "UPDATE `pages` SET
`title` = ?, `heading` = ?, `description` = ?, `keywords` = ?, `author` = ?,
$db->query($query, $params); `slug` = ?, `path` = ?, `intro` = ?, `body` = ?, `notes` = ?,
`draft` = ?, `changefreq` = ?, `priority` = ?, `updated` = NOW()
$messages->notice('Page Saved'); WHERE `id` = ?";
$params = [
$title, $heading, $description, $keywords, $author,
$slug, $path, $intro, $body, $notes,
$draft, $changefreq, $priority, $id
];
$db->query($query, $params);
$messages->notice('Page Updated');
} else {
// Create new page
$query = "INSERT INTO `pages`
(`title`, `heading`, `description`, `keywords`, `author`,
`slug`, `path`, `intro`, `body`, `notes`,
`draft`, `changefreq`, `priority`, `created`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())";
$params = [
$title, $heading, $description, $keywords, $author,
$slug, $path, $intro, $body, $notes,
$draft, $changefreq, $priority
];
$db->query($query, $params);
$id = $db->lastid; // Get new page ID
$messages->notice('Page Created');
}
} catch (Exception $e) { } catch (Exception $e) {
$messages->error($e->getMessage());
$messages->notice($e->getMessage()); $redirect->url($url_error);
makeitso();
} }
// Redirect to edit page
$redirect->url('/novaconium/page/edit/' . $id); $redirect->url('/novaconium/page/edit/' . $id);

View File

@ -4,6 +4,7 @@
<li><a href="/">Home</a></li> <li><a href="/">Home</a></li>
<li><a href="/novaconium/dashboard">Dashboard</a></li> <li><a href="/novaconium/dashboard">Dashboard</a></li>
<li><a href="/novaconium/pages">Pages</a></li> <li><a href="/novaconium/pages">Pages</a></li>
<li><a href="/novaconium/messages">Messages</a></li>
<li><a href="/novaconium/logout">Logout</a></li> <li><a href="/novaconium/logout">Logout</a></li>
</ul> </ul>
</div> </div>

View File

@ -7,7 +7,7 @@
{% include ['@override/head.html.twig', '@novaconium/head.html.twig'] %} {% include ['@override/head.html.twig', '@novaconium/head.html.twig'] %}
</head> </head>
<body id="{{ pageid | default('pageid') }}"> <body id="{{ pageid | default('pageid') }}" class="{{ pageclass | default('pageclass') }}" >
{# Page Header #} {# Page Header #}
<header> <header>

View File

@ -5,5 +5,4 @@
<p>Dashboard page</p> <p>Dashboard page</p>
<p><a href="/">Homepage</a></p> <p><a href="/">Homepage</a></p>
<p><a href="/novaconium/logout">logout</p> <p><a href="/novaconium/logout">logout</p>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,30 @@
{% extends '@novaconium/master.html.twig' %}
{% block content %}
<h2>Edit Message - {{ title }}</h2>
<p><a href="/novaconium/messages/delete/{{ themessage.id }}">Delete</a></p>
<form method="post" action="/novaconium/message_save">
<input type="hidden" name="id" value="{{ themessage.id }}">
<input type="hidden" name="token" value="{{ token }}">
<label for="name">Name:</label>
<input type="text" id="name" name="name" value="{{ themessage.name }}" required>
<label for="email">Email:</label>
<input type="email" id="email" name="email" value="{{ themessage.email }}" required>
<label for="message">Message:</label>
<textarea id="message" name="message" rows="10" required>{{ themessage.message }}</textarea>
<label for="unread">
<input type="checkbox" id="unread" name="unread" value="1" {% if themessage.unread %}checked{% endif %}>
Unread
</label>
<p><strong>Created:</strong> {{ themessage.created|date("Y-m-d H:i:s") }}</p>
<button type="submit">Save Changes</button>
</form>
{% endblock %}

View File

@ -1,32 +1,61 @@
{% extends '@novaconium/master.html.twig' %} {% extends '@novaconium/master.html.twig' %}
{% block content %} {% block content %}
<h2>Edit Page - {{ title }}</h2> <h2>Edit Page - {{ title }}</h2>
<form method="post" action="/novaconium/savePage"> <form method="post" action="/novaconium/savePage">
<input type="hidden" name="id" value="{{ rows.id }}"> <input type="hidden" name="id" value="{{ rows.id }}">
<input type="hidden" name="token" value="{{ token }}"> <input type="hidden" name="token" value="{{ token }}">
<label for="title">Title:</label> <label for="title">Title:</label>
<input type="text" id="title" name="title" value="{{ rows.title }}" required> <input type="text" id="title" name="title" value="{{ rows.title }}" required>
<label for="slug">Slug: (<a href="/page/{{ rows.slug }}" target="_new">/page/{{ rows.slug }}</a>)</label> <label for="heading">Heading:</label>
<input type="text" id="slug" name="slug" value="{{ rows.slug }}" required> <input type="text" id="heading" name="heading" value="{{ rows.heading }}">
<label for="body">Body:</label> <label for="description">Description:</label>
<textarea id="body" name="body" rows="10" required>{{ rows.body }}</textarea> <input type="text" id="description" name="description" value="{{ rows.description }}">
<label for="intro">Intro:</label> <label for="keywords">Keywords:</label>
<textarea id="intro" name="intro" rows="10" required>{{ rows.intro }}</textarea> <input type="text" id="keywords" name="keywords" value="{{ rows.keywords }}">
<label for="draft"> <label for="author">Author:</label>
<input type="checkbox" id="draft" name="draft" value="1" {% if rows.draft %}checked{% endif %}> <input type="text" id="author" name="author" value="{{ rows.author }}">
Save as Draft
</label>
<p><strong>Created:</strong> {{ rows.created|date("Y-m-d H:i:s") }}</p> <label for="slug">Slug: (<a href="/page/{{ rows.slug }}" target="_new">/page/{{ rows.slug }}</a>)</label>
<p><strong>Last Updated:</strong> {{ rows.updated|date("Y-m-d H:i:s") }}</p> <input type="text" id="slug" name="slug" value="{{ rows.slug }}" required>
<button type="submit">Save Changes</button> <label for="path">Path:</label>
</form> <input type="text" id="path" name="path" value="{{ rows.path }}">
<label for="intro">Intro:</label>
<textarea id="intro" name="intro" rows="5">{{ rows.intro }}</textarea>
<label for="body">Body:</label>
<textarea id="body" name="body" rows="10">{{ rows.body }}</textarea>
<label for="notes">Notes:</label>
<textarea id="notes" name="notes" rows="5">{{ rows.notes }}</textarea>
<label for="draft">
<input type="checkbox" id="draft" name="draft" value="1" {% if rows.draft %}checked{% endif %}>
Save as Draft
</label>
<label for="changefreq">Change Frequency:</label>
<select id="changefreq" name="changefreq">
{% set freqs = ['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'] %}
{% for freq in freqs %}
<option value="{{ freq }}" {% if rows.changefreq == freq %}selected{% endif %}>{{ freq|capitalize }}</option>
{% endfor %}
</select>
<label for="priority">Priority (0.0 - 1.0):</label>
<input type="number" id="priority" name="priority" value="{{ rows.priority }}" step="0.1" min="0" max="1">
<p><strong>Created:</strong> {{ rows.created|date("Y-m-d H:i:s") }}</p>
<p><strong>Last Updated:</strong> {{ rows.updated|date("Y-m-d H:i:s") }}</p>
<button type="submit">Save Changes</button>
</form>
{% endblock %} {% endblock %}

43
views/messages.html.twig Normal file
View File

@ -0,0 +1,43 @@
{% extends '@novaconium/master.html.twig' %}
{% block content %}
<h1>{{title}}</h1>
<table class="messages-table">
<thead>
<tr>
<th>Email</th>
<th>Name</th>
<th>Message Preview</th>
<th>Created</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for msg in messages %}
<tr class="{{ msg.unread ? 'unread' : 'read' }}">
<td><a href="mailto:{{ msg.email }}">{{ msg.email }}</a></td>
<td>{{ msg.name }}</td>
<td>{{ msg.message }}</td>
<td>{{ msg.created|date('Y-m-d H:i') }}</td>
<td>
{% if msg.unread %}
<strong>Unread</strong>
{% else %}
Read
{% endif %}
</td>
<td>
<a href="/novaconium/messages/edit/{{ msg.id }}" class="btn btn-edit">Edit</a>
<a href="/novaconium/messages/delete/{{ msg.id }}">Delete</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="7" style="text-align:center;">No messages found</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -2,6 +2,7 @@
{% block content %} {% block content %}
<h1>{{title}}</h1> <h1>{{title}}</h1>
<p><a href="/novaconium/page/create">Create Page</a></p>
<table class="pages-table"> <table class="pages-table">
<thead> <thead>
<tr> <tr>