Files
rangerhq-logbook/inc/wp-notes-about.php
T
ranger 5c8f1716a3 release: 3.2.0 → 3.3.0 — self-hosted update checker (Gitea API)
WP Logbook is hosted on the author's own Gitea instance
(git.davidtkeane.com), not on WordPress.org, so WP's built-in update
flow doesn't see new releases. This release adds a Settings →
Updates panel that polls Gitea's Releases API and reports whether
a newer version is available.

CHANGES
- inc/wp-notes-updater.php: full rewrite of the previous broken stub
  (it had a hard require on a non-existent vendor path and was never
  included from the main plugin file anyway).
- wp_notes_fetch_latest_release() hits
  /api/v1/repos/<owner>/<repo>/releases/latest, parses, normalises.
  Prefers a .zip asset attached to the release; falls back to
  Gitea's source-archive zip URL.
- wp_notes_update_status() compares against WP_NOTES_VERSION and
  returns 'available' | 'up-to-date' | 'unknown' (the last when no
  release has been tagged yet — graceful first-run UX since the
  repo currently has zero tags).
- New AJAX endpoint wp_notes_check_updates, capability-gated
  (manage_options) + nonce-protected. Force-refreshes the cache.
- Settings page now renders the Updates panel via
  wp_notes_render_updates_panel() — current status text, "Check
  now" button, View on Gitea / View all releases quick links,
  manual-install instructions, and a Download .zip button + View
  release notes link when an update is detected.
- wp-notes.php require_once chain now includes the updater file.

CACHING
- Successful fetches: 12h site transient.
- Negative responses (404 = no releases yet): 1h so a freshly-
  tagged release shows up quickly.

INSTALLATION FLOW (intentionally manual)
The panel does NOT auto-install. Manual path printed in the panel:
download .zip → deactivate → upload via Plugins → Add New → Upload
→ reactivate. Notes live in wp_options so they survive the upgrade.

ALSO IN 3.3.0
- Section heading rename carried from the previous unreleased
  block: "Add New Note" → "New Log Entry"; "Notes Todo List:" →
  "Log entries". Row-level "note" labels intentionally unchanged.

VERSION BUMP
- wp-notes.php header 3.2.0 → 3.3.0
- WP_NOTES_VERSION constant 3.2.0 → 3.3.0
- About page version history leads with v3.3.0 as latest, demotes
  v3.2.0 to previous entry

NOTES FOR FUTURE-CLAUDE
- Gitea repo currently has ZERO release tags. First run will show
  "No releases tagged on the Gitea repo yet." Tag v3.2.0 / v3.3.0
  on Gitea and the checker will start reporting versions.
- Repo coordinates live in three constants at the top of
  inc/wp-notes-updater.php (WP_NOTES_GITEA_HOST, _OWNER, _REPO).
  Override via define() in wp-config.php if the repo ever moves.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 09:09:40 +01:00

274 lines
15 KiB
PHP

<?php
// wp-notes-about.php
/**
* Function to display the "About" page for WP Logbook plugin.
*/
function wp_notes_about_page() {
?>
<style>
/* Banner + intro side-by-side row at the top of the About page.
Stacks vertically on narrower screens. */
.wp-notes-about-intro {
display: flex;
gap: 24px;
align-items: center;
flex-wrap: wrap;
margin: 16px 0 28px;
padding: 18px;
background: #fff;
border: 1px solid #ccd0d4;
border-radius: 4px;
}
.wp-notes-about-intro__img {
flex: 0 0 320px;
max-width: 320px;
}
.wp-notes-about-intro__img img {
display: block;
width: 100%;
height: auto;
border-radius: 4px;
}
.wp-notes-about-intro__body {
flex: 1 1 320px;
min-width: 0;
}
.wp-notes-about-intro__body h2 {
margin-top: 0;
}
</style>
<div class="wrap">
<h1 class="wp-heading-inline">About</h1>
<span class="page-title-action">v<?php echo esc_html(WP_NOTES_VERSION); ?></span>
<hr class="wp-header-end">
</div>
<div class="wrap" style="display: flex; gap: 20px;">
<!-- Left Section: About Content (70%) -->
<div style="flex: 0 0 70%;">
<!-- Banner + intro, side by side -->
<div class="wp-notes-about-intro">
<div class="wp-notes-about-intro__img">
<img src="<?php echo esc_url(WP_NOTES_URL); ?>assets/wp-notes-banner.jpg"
alt="WP Logbook banner">
</div>
<div class="wp-notes-about-intro__body">
<h2>WP Logbook <span style="color:#646970; font-weight:400;">v<?php echo esc_html(WP_NOTES_VERSION); ?></span></h2>
<p>WP Logbook is a lightweight task &amp; logbook plugin for WordPress. Log your daily work, mark tasks as done, and keep a tidy record right inside the dashboard &mdash; perfect for freelancers showing clients what's been delivered.</p>
<p style="margin-bottom:0;">
<a href="<?php echo esc_url(admin_url('admin.php?page=wp-notes')); ?>" class="button button-primary">Go to My Log →</a>
</p>
</div>
</div>
<style>
/* Hide most plugin notices on the About page — they push
the long-form content down and the user came here to
read, not to dismiss admin chatter. */
.notice, .updated, .error { display: none !important; }
/* About-page content cards — same visual rhythm as the
intro row above. */
.wp-notes-about-card {
background: #fff;
border: 1px solid #ccd0d4;
border-radius: 4px;
padding: 20px 24px;
margin: 0 0 22px;
}
.wp-notes-about-card h2 {
margin: 0 0 10px;
font-size: 16px;
}
.wp-notes-about-card p:last-child { margin-bottom: 0; }
.wp-notes-about-card ul {
margin: 8px 0 0 18px;
list-style: disc;
}
.wp-notes-about-card ul li { margin-bottom: 4px; }
.wp-notes-about-card--versions ul { list-style: none; margin-left: 0; }
.wp-notes-about-card--versions li { margin-bottom: 12px; }
.wp-notes-about-card--versions .ver { font-weight: 600; color: #2271b1; }
.wp-notes-about-card--versions .latest { display: inline-block; margin-left: 6px; padding: 1px 7px; background: #00a32a; color: #fff; border-radius: 9px; font-size: 11px; font-weight: 600; }
.wp-notes-about-changelog-link {
display: inline-block;
margin-top: 6px;
font-size: 13px;
color: #646970;
}
</style>
<!-- What WP Logbook does -->
<div class="wp-notes-about-card">
<h2>What WP Logbook does</h2>
<p>WP Logbook is a lightweight task &amp; logbook plugin that lives entirely inside the WordPress admin. Type a note, format it with colour / size / font / emoji, mark it done when the work is finished, restore it later if you need to revisit. Everything is stored in the site's own database &mdash; nothing leaves your server.</p>
<p>I built it for my own client work as a transparent &ldquo;here's what I did this week&rdquo; logbook, so customers can see clearly what they're paying for. It turned out to be just as useful for any small team or single user who wants notes attached to the WordPress dashboard rather than a separate app.</p>
</div>
<!-- Who it's for -->
<div class="wp-notes-about-card">
<h2>Who it's for</h2>
<ul>
<li><strong>Freelancers &amp; site developers</strong> tracking work done on client sites.</li>
<li><strong>Small teams</strong> documenting changes or keeping a project changelog inside the dashboard.</li>
<li><strong>WordPress power users</strong> who'd rather not jump out to a separate notes app.</li>
<li><strong>Small businesses</strong> needing a simple task list tied to their website.</li>
<li><strong>Students &amp; teachers</strong> logging daily progress.</li>
</ul>
</div>
<!-- Version history (compact, accurate) -->
<div class="wp-notes-about-card wp-notes-about-card--versions">
<h2>Version history</h2>
<ul>
<li>
<span class="ver">v3.3.0</span> &mdash; 25 May 2026 <span class="latest">latest</span><br>
Self-hosted update checker. Settings &rarr; Updates panel polls the Gitea repo via its JSON API, compares against the running version, and shows a download link when a new release is tagged. Includes &ldquo;View on Gitea&rdquo; and &ldquo;View all releases&rdquo; quick links. No auto-install &mdash; manual download keeps things safe.
</li>
<li>
<span class="ver">v3.2.0</span> &mdash; 25 May 2026<br>
Renamed to <strong>WP Logbook</strong> to match what the plugin is actually becoming &mdash; a work logbook for freelancers and students, not just a notes pad. Menu submenu renamed <em>My Notes</em> &rarr; <em>My Log</em>. Internal storage and slugs unchanged, no data migration.
</li>
<li>
<span class="ver">v3.1.0</span> &mdash; 25 May 2026<br>
UX polish + bug-fix pass. Single-H1 cleanup, banner moved to this About page, menu renamed to <em>My Notes</em>, duplicate forms removed, empty-state notice now persistently dismissible per-user via <code>user_meta</code>, Tools shortcut retired with a backward-compatible redirect.
</li>
<li>
<span class="ver">v3.0.2</span> &mdash; 10 May 2025<br>
The &ldquo;without all the crap&rdquo; trim-back from the v1.1.5 feature-creep era (AI chat, tamagotchi, journal, speedtest&hellip; gone). Baseline of what the plugin is today: notes, admin bar, settings, import/export, about, updater.
</li>
<li>
<span class="ver">v2.x</span> &mdash; 2024<br>
Editor improvements, AJAX edits, mark-as-done / restore, color &amp; font / size customisation, JSON + CSV import/export, user-attribution &amp; timestamps, dashboard widget.
</li>
<li>
<span class="ver">v2.0.0</span> &mdash; initial release<br>
Basic note functionality with the dashboard widget and styling options.
</li>
</ul>
<a class="wp-notes-about-changelog-link" href="https://git.davidtkeane.com/ranger/a-wp-notes-v3/src/branch/main/CHANGELOG.md" target="_blank" rel="noopener">View the full CHANGELOG.md →</a>
</div>
</div>
<!-- Right Section: Feedback Box (30%) -->
<div style="flex: 0 0 30%; padding: 20px; border: 1px solid #ddd; background: #f9f9f9;">
<h2>Leave Feedback</h2>
<!-- Social Buttons -->
<button style="background-color: black; color: white; padding: 10px 20px; border: none; margin: 5px; border-radius: 5px; cursor: pointer;">
✖️ Post
</button>
<button style="background-color: #FF0000; color: white; padding: 10px 20px; border: none; margin: 5px; border-radius: 5px; cursor: pointer;">
🔴 YouTube 1K
</button>
<a href="https://github.com/davidtkeane/wp-notes" target="_blank" style="text-decoration: none;">
<button style="background-color: #24292e; color: white; padding: 10px 20px; border: none; margin: 5px; border-radius: 5px; cursor: pointer;">
🐙 GitHub
</button>
</a>
<!-- Feedback Options -->
<form id="wp-notes-feedback-options" style="margin-top: 20px;">
<p style="margin: 0 0 8px; font-weight: 600;">What's on your mind? <span style="font-weight: 400; color: #646970;">(pick any)</span></p>
<label style="display:block; margin-bottom:6px;"><input type="checkbox" name="feedback_topics[]" value="improve"> I have ideas to improve this plugin</label>
<label style="display:block; margin-bottom:6px;"><input type="checkbox" name="feedback_topics[]" value="help"> I need help with this plugin</label>
<label style="display:block; margin-bottom:6px;"><input type="checkbox" name="feedback_topics[]" value="bug"> I found a bug</label>
<label style="display:block; margin-bottom:6px;"><input type="checkbox" name="feedback_topics[]" value="feature"> I'd like to request a new feature</label>
<label style="display:block; margin-bottom:6px;"><input type="checkbox" name="feedback_topics[]" value="use-case"> I'd like to share my use case</label>
<label style="display:block; margin-bottom:6px;"><input type="checkbox" name="feedback_topics[]" value="thanks"> Just saying thanks 🍀</label>
<label style="display:block; margin-bottom:10px;"><input type="checkbox" name="feedback_topics[]" value="other"> Other</label>
<p style="margin: 12px 0 4px; font-weight: 600;">Anything to add? <span style="font-weight: 400; color: #646970;">(optional)</span></p>
<textarea name="feedback_message" rows="4" style="width: 100%; box-sizing: border-box;" placeholder="A few sentences with more detail…"></textarea>
<?php wp_nonce_field('wp_notes_feedback_submit', 'wp_notes_feedback_nonce'); ?>
<p style="margin-top: 12px; margin-bottom: 0;">
<input type="submit" id="wp-notes-feedback-submit" value="Submit Feedback" class="button button-primary">
</p>
<p id="wp-notes-feedback-status" role="status" style="margin: 10px 0 0; min-height: 1.4em;"></p>
</form>
<br>
<!-- Buy Me a Coffee Button -->
<a href="https://www.buymeacoffee.com/davidkeanek" target="_blank">
<img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=davidkeanek&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff" alt="Buy me a coffee">
</a>
<br>
</div>
</div>
<!-- JavaScript to toggle About section -->
<script>
/**
* Function to toggle the display of a section.
* @param {string} sectionId - The ID of the section to toggle.
*/
function toggleSection(sectionId) {
var section = document.getElementById(sectionId);
if (section) {
if (section.style.display === "none") {
section.style.display = "block";
} else {
section.style.display = "none";
}
} else {
console.error("Element with ID " + sectionId + " not found.");
}
}
// Submit the feedback form → AJAX → wp_mail() to the site admin.
// No toggleSection() shuffle anymore (the old code targeted IDs
// that never existed). Validates that at least one topic is
// checked, otherwise the submit is a no-op with a hint.
document.getElementById('wp-notes-feedback-options').addEventListener('submit', function(e) {
e.preventDefault();
var form = e.target;
var btn = document.getElementById('wp-notes-feedback-submit');
var statusEl = document.getElementById('wp-notes-feedback-status');
var topics = Array.from(form.querySelectorAll('input[name="feedback_topics[]"]:checked')).map(function (i) { return i.value; });
var message = (form.querySelector('textarea[name="feedback_message"]').value || '').trim();
var nonce = (form.querySelector('input[name="wp_notes_feedback_nonce"]').value || '');
if (topics.length === 0 && message === '') {
statusEl.textContent = 'Pick at least one option (or write a message) before submitting.';
statusEl.style.color = '#8a2424';
return;
}
btn.disabled = true;
btn.value = 'Sending…';
statusEl.textContent = '';
statusEl.style.color = '';
var fd = new FormData();
fd.append('action', 'wp_notes_submit_feedback');
fd.append('nonce', nonce);
topics.forEach(function (t) { fd.append('topics[]', t); });
fd.append('message', message);
fetch(ajaxurl, { method: 'POST', credentials: 'same-origin', body: fd })
.then(function (r) { return r.json(); })
.then(function (res) {
if (res && res.success) {
form.innerHTML = '<p style="color:#1e6e40; font-weight:600; margin:0;">Thanks — your feedback has been sent. 🍀</p>';
} else {
statusEl.textContent = (res && res.data) ? String(res.data) : 'Sorry, something went wrong. Please try again.';
statusEl.style.color = '#8a2424';
btn.disabled = false;
btn.value = 'Submit Feedback';
}
})
.catch(function () {
statusEl.textContent = 'Network error — please try again in a moment.';
statusEl.style.color = '#8a2424';
btn.disabled = false;
btn.value = 'Submit Feedback';
});
});
</script>
<?php
}
?>