feat(ux): add activation redirect, loading state overlay, and direct view list button in notice
This commit is contained in:
+74
-14
@@ -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> • <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) . ' →</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();
|
||||
|
||||
Reference in New Issue
Block a user