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;
if (!empty($pageid)) {
// Existing page: fetch from database
$query = <<<EOSQL
SELECT SELECT
id, id,
title, title,
intro, heading,
description,
keywords,
author,
slug, slug,
path,
intro,
body, body,
notes,
draft, draft,
changefreq,
priority,
created, created,
updated updated
FROM pages FROM pages
WHERE id = '$pageid' 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;
}
}
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('@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();
} }
// Gather POST data
$id = $post->get('id'); $id = $post->get('id');
$slug = $post->get('slug'); $title = $_POST['title'] ?? '';
$title = $_POST['title']; $heading = $_POST['heading'] ?? '';
$body = $_POST['body']; // We want it dirty $description = $_POST['description'] ?? '';
$intro = $_POST['intro']; // We want it dirty $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` = ?,
`slug` = ?, `path` = ?, `intro` = ?, `body` = ?, `notes` = ?,
`draft` = ?, `changefreq` = ?, `priority` = ?, `updated` = NOW()
WHERE `id` = ?";
$params = [
$title, $heading, $description, $keywords, $author,
$slug, $path, $intro, $body, $notes,
$draft, $changefreq, $priority, $id
];
$db->query($query, $params); $db->query($query, $params);
$messages->notice('Page Updated');
$messages->notice('Page Saved'); } 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="heading">Heading:</label>
<input type="text" id="heading" name="heading" value="{{ rows.heading }}">
<label for="description">Description:</label>
<input type="text" id="description" name="description" value="{{ rows.description }}">
<label for="keywords">Keywords:</label>
<input type="text" id="keywords" name="keywords" value="{{ rows.keywords }}">
<label for="author">Author:</label>
<input type="text" id="author" name="author" value="{{ rows.author }}">
<label for="slug">Slug: (<a href="/page/{{ rows.slug }}" target="_new">/page/{{ rows.slug }}</a>)</label> <label for="slug">Slug: (<a href="/page/{{ rows.slug }}" target="_new">/page/{{ rows.slug }}</a>)</label>
<input type="text" id="slug" name="slug" value="{{ rows.slug }}" required> <input type="text" id="slug" name="slug" value="{{ rows.slug }}" required>
<label for="body">Body:</label> <label for="path">Path:</label>
<textarea id="body" name="body" rows="10" required>{{ rows.body }}</textarea> <input type="text" id="path" name="path" value="{{ rows.path }}">
<label for="intro">Intro:</label> <label for="intro">Intro:</label>
<textarea id="intro" name="intro" rows="10" required>{{ rows.intro }}</textarea> <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"> <label for="draft">
<input type="checkbox" id="draft" name="draft" value="1" {% if rows.draft %}checked{% endif %}> <input type="checkbox" id="draft" name="draft" value="1" {% if rows.draft %}checked{% endif %}>
Save as Draft Save as Draft
</label> </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>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> <p><strong>Last Updated:</strong> {{ rows.updated|date("Y-m-d H:i:s") }}</p>
<button type="submit">Save Changes</button> <button type="submit">Save Changes</button>
</form> </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>