feat(ux): add activation redirect, loading state overlay, and direct view list button in notice

This commit is contained in:
idtemankampus-creator
2026-09-18 08:22:45 +07:00
parent 593d39ffe6
commit ad2aa48b97
+74 -14
View File
@@ -3,7 +3,7 @@
* Plugin Name: DummyLab Dummy Post & Content Generator
* Plugin URI: https://apps.masbudikusuma.my.id/dummylab-wp
* Description: Advanced dummy content generator for WordPress development with safety controls and bulk purge features.
* Version: 1.1.0
* Version: 1.2.0
* Author: masbudikusuma
* Author URI: https://masbudi.my.id
* Text Domain: dummylab
@@ -28,10 +28,25 @@ class DummyLab {
private function __construct() {
add_action('admin_menu', [$this, 'add_admin_menu']);
add_action('admin_init', [$this, 'handle_activation_redirect']);
add_action('admin_post_dummylab_generate', [$this, 'handle_generate']);
add_action('admin_post_dummylab_purge', [$this, 'handle_purge']);
}
public static function activate_plugin() {
add_option('dummylab_do_activation_redirect', true);
}
public function handle_activation_redirect() {
if (get_option('dummylab_do_activation_redirect', false)) {
delete_option('dummylab_do_activation_redirect');
if (!isset($_GET['activate-multi'])) {
wp_safe_redirect(admin_url('tools.php?page=dummylab'));
exit;
}
}
}
public function add_admin_menu() {
add_management_page(
'DummyLab Generator',
@@ -99,21 +114,33 @@ class DummyLab {
.dummylab-badge-count { display: inline-block; background: #fcf0f0; color: #d63638; font-weight: 700; font-size: 16px; padding: 4px 12px; border-radius: 20px; border: 1px solid #f5c6cb; margin-left: 6px; }
.dummylab-guide-list { margin: 0; padding-left: 20px; color: #3c434a; font-size: 13px; line-height: 1.6; }
.dummylab-guide-list li { margin-bottom: 8px; }
.dummylab-guide-list li:last-child { margin-bottom: 0; }
.dummylab-safety-list { margin: 0; padding-left: 18px; color: #3c434a; font-size: 13px; line-height: 1.6; list-style-type: square; }
.dummylab-safety-list li { margin-bottom: 6px; }
.dummylab-btn-primary { background: #2271b1 !important; border-color: #2271b1 !important; border-radius: 6px !important; padding: 6px 18px !important; font-size: 14px !important; height: auto !important; }
.dummylab-btn-primary { background: #2271b1 !important; border-color: #2271b1 !important; border-radius: 6px !important; padding: 8px 20px !important; font-size: 14px !important; height: auto !important; cursor: pointer; }
.dummylab-btn-danger { background: #d63638 !important; border-color: #d63638 !important; color: #fff !important; border-radius: 6px !important; padding: 6px 18px !important; font-size: 13px !important; height: auto !important; width: 100%; text-align: center; }
.dummylab-btn-danger:disabled { background: #f6f7f7 !important; border-color: #dcdcde !important; color: #a7aaad !important; cursor: not-allowed; }
/* Loading Overlay Styles */
.dummylab-loading-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(15, 23, 42, 0.6); backdrop-filter: blur(4px); z-index: 999999; align-items: center; justify-content: center; flex-direction: column; color: #fff; }
.dummylab-spinner { width: 50px; height: 50px; border: 5px solid rgba(255, 255, 255, 0.3); border-radius: 50%; border-top-color: #38bdf8; animation: dummylab-spin 1s ease-in-out infinite; margin-bottom: 16px; }
@keyframes dummylab-spin { to { transform: rotate(360deg); } }
.dummylab-loading-text { font-size: 18px; font-weight: 600; text-align: center; }
.dummylab-loading-subtext { font-size: 13px; color: #cbd5e1; margin-top: 6px; text-align: center; }
</style>
<!-- Loading Overlay Element -->
<div id="dummylab-loading-overlay" class="dummylab-loading-overlay">
<div class="dummylab-spinner"></div>
<div class="dummylab-loading-text"><?php echo $t['loading_title']; ?></div>
<div class="dummylab-loading-subtext"><?php echo $t['loading_subtitle']; ?></div>
</div>
<div class="dummylab-wrap">
<!-- Header Banner -->
<div class="dummylab-header">
<div>
<h1>🧪 DummyLab <span style="font-size: 14px; font-weight: 400; color: #646970;">v1.1.0</span></h1>
<h1>🧪 DummyLab <span style="font-size: 14px; font-weight: 400; color: #646970;">v1.2.0</span></h1>
<p><?php echo $t['created_by']; ?> <a href="https://masbudi.my.id" target="_blank" style="text-decoration: none; font-weight: 600; color: #2271b1;">masbudikusuma</a> &bull; <a href="https://apps.masbudikusuma.my.id/dummylab-wp" target="_blank" style="text-decoration: none; color: #2271b1;"><?php echo $t['plugin_doc']; ?></a></p>
</div>
<!-- UI Language Switcher -->
@@ -124,13 +151,18 @@ class DummyLab {
</div>
<?php if (isset($_GET['status'])): ?>
<div class="notice notice-success is-dismissible" style="border-radius: 6px; margin-bottom: 20px;">
<p style="font-size: 14px;">
<div class="notice notice-success is-dismissible" style="border-radius: 6px; margin-bottom: 20px; padding: 12px 16px;">
<p style="font-size: 14px; margin: 0; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;">
<?php
if ($_GET['status'] === 'generated') {
echo '🎉 <strong>' . esc_html(intval($_GET['count'])) . '</strong> ' . esc_html($t['msg_generated']);
$gen_type = isset($_GET['type']) && $_GET['type'] === 'page' ? 'page' : 'post';
$type_label = ($gen_type === 'page') ? ($ui_lang === 'en' ? 'Pages' : 'Halaman (Page)') : ($ui_lang === 'en' ? 'Posts' : 'Post');
$target_url = ($gen_type === 'page') ? admin_url('edit.php?post_type=page') : admin_url('edit.php');
echo '<span>🎉 <strong>' . esc_html(intval($_GET['count'])) . '</strong> ' . esc_html($t['msg_generated']) . ' ' . sprintf(esc_html($t['check_msg']), '<strong>' . esc_html($type_label) . '</strong>') . '</span>';
echo '<a href="' . esc_url($target_url) . '" class="button button-secondary" style="font-weight: 600; text-decoration: none;">' . esc_html($t['btn_view_list']) . ' ' . esc_html($type_label) . ' &rarr;</a>';
} elseif ($_GET['status'] === 'purged') {
echo '🧹 <strong>' . esc_html(intval($_GET['count'])) . '</strong> ' . esc_html($t['msg_purged']);
echo '<span>🧹 <strong>' . esc_html(intval($_GET['count'])) . '</strong> ' . esc_html($t['msg_purged']) . '</span>';
}
?>
</p>
@@ -140,7 +172,7 @@ class DummyLab {
<div class="dummylab-container">
<!-- Left Main Form -->
<div class="dummylab-main-card">
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
<form id="dummylab-generate-form" method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
<?php wp_nonce_field('dummylab_generate_action', 'dummylab_nonce'); ?>
<input type="hidden" name="action" value="dummylab_generate">
<input type="hidden" name="ui_lang" value="<?php echo esc_attr($ui_lang); ?>">
@@ -238,7 +270,7 @@ class DummyLab {
</div>
<div style="margin-top: 24px;">
<?php submit_button($t['btn_generate'], 'primary dummylab-btn-primary', 'submit', false); ?>
<input type="submit" id="dummylab-submit-btn" class="button button-primary dummylab-btn-primary" value="<?php echo esc_attr($t['btn_generate']); ?>">
</div>
</form>
</div>
@@ -283,6 +315,25 @@ class DummyLab {
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var form = document.getElementById('dummylab-generate-form');
if (form) {
form.addEventListener('submit', function() {
var overlay = document.getElementById('dummylab-loading-overlay');
var btn = document.getElementById('dummylab-submit-btn');
if (overlay) {
overlay.style.display = 'flex';
}
if (btn) {
btn.disabled = true;
btn.value = '⏳ Generating...';
}
});
}
});
</script>
<?php
}
@@ -291,8 +342,12 @@ class DummyLab {
return [
'created_by' => 'Created by',
'plugin_doc' => 'Plugin Documentation',
'msg_generated' => 'dummy posts generated successfully!',
'msg_generated' => 'dummy item(s) generated successfully!',
'check_msg' => 'Please check your %s section.',
'btn_view_list' => 'View List of',
'msg_purged' => 'dummy items deleted successfully!',
'loading_title' => 'Generating dummy content...',
'loading_subtitle' => 'Please wait a few moments while we create your test data and images.',
'sec_general' => 'General Settings',
'sec_taxonomy' => 'Taxonomy & Author',
'sec_content' => 'Content & Media',
@@ -331,7 +386,7 @@ class DummyLab {
'purge_title' => 'Cleanup & Purge',
'purge_active' => 'Active dummy items',
'purge_desc' => 'Permanently deletes all posts, pages, and media attachments created by DummyLab.',
'btn_purge' => 'Hapus Semua Data Dummy',
'btn_purge' => 'Delete All Dummy Data',
'guide_title' => 'Quick Usage Guide',
'guide_step1' => 'Select total count and content type (Post/Page).',
'guide_step2' => 'Choose generated text language and length.',
@@ -348,7 +403,11 @@ class DummyLab {
'created_by' => 'Dibuat oleh',
'plugin_doc' => 'Dokumentasi Plugin',
'msg_generated' => 'konten dummy berhasil dibuat!',
'check_msg' => 'Silakan cek daftar %s Anda.',
'btn_view_list' => 'Lihat Daftar',
'msg_purged' => 'data dummy berhasil dibersihkan!',
'loading_title' => 'Sedang membuat konten dummy...',
'loading_subtitle' => 'Mohon tunggu beberapa saat. Server sedang mengunduh gambar dan membuat data artikel.',
'sec_general' => 'Pengaturan Utama',
'sec_taxonomy' => 'Taksonomi & Penulis',
'sec_content' => 'Konten & Media',
@@ -517,7 +576,7 @@ class DummyLab {
}
}
wp_redirect(admin_url('tools.php?page=dummylab&ui_lang=' . $ui_lang . '&status=generated&count=' . $count));
wp_redirect(admin_url('tools.php?page=dummylab&ui_lang=' . $ui_lang . '&status=generated&count=' . $count . '&type=' . $post_type));
exit;
}
@@ -600,4 +659,5 @@ class DummyLab {
}
}
register_activation_hook(__FILE__, ['DummyLab', 'activate_plugin']);
DummyLab::get_instance();