feat: belegte domains als liste mit papierkorb + status-live-refresh

- Bei voller Lizenz werden alle belegten Domains untereinander gelistet, je
  mit Papierkorb-Button + Bestaetigungsdialog (statt Dropdown).
- Trash gibt die Domain frei (deaktiviert serverseitig) und aktiviert diese Seite.
- Lizenz-Tab re-validiert den Status live (max alle 5 Min), damit eine an anderer
  Stelle freigegebene Domain hier sofort als ungueltig erscheint statt stale aktiv.
- EN-Uebersetzung (122) aktualisiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
s4luorth
2026-06-07 15:27:34 +02:00
parent 4f0f8ea170
commit a0972b4bbf
5 changed files with 69 additions and 31 deletions

View File

@@ -323,7 +323,17 @@ class CB_License {
}
public static function render_tab(): void {
$lic = self::get_license();
$lic = self::get_license();
// Keep the shown status honest: if this site was deactivated elsewhere
// (e.g. another site freed this slot), re-validate live when the tab is
// opened — throttled to at most once every 5 minutes.
if ( in_array( $lic['status'], [ 'active', 'invalid' ], true )
&& ( time() - (int) $lic['last_check'] ) > 5 * MINUTE_IN_SECONDS ) {
self::cron_check();
$lic = self::get_license();
}
$status = $lic['status'];
$badge = match ( $status ) {
@@ -349,27 +359,32 @@ class CB_License {
</tbody></table>
<?php if ( $status === 'limit' && ! empty( $lic['pending_domains'] ) ) : ?>
<!-- No free slots: let the user release one bound domain and activate here. -->
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
<?php wp_nonce_field( 'cb_license', 'cb_license_nonce' ); ?>
<input type="hidden" name="action" value="cb_license_swap">
<table class="form-table" role="presentation"><tbody>
<tr>
<th scope="row"><label for="cb_release_domain"><?php esc_html_e( 'Domain freigeben', 'gdpr-content-blocker' ); ?></label></th>
<td>
<select id="cb_release_domain" name="cb_release_domain">
<?php foreach ( $lic['pending_domains'] as $d ) : ?>
<option value="<?php echo esc_attr( $d ); ?>"><?php echo esc_html( $d ); ?></option>
<?php endforeach; ?>
</select>
<p class="description">
<?php esc_html_e( 'Diese Lizenz ist bereits auf den genannten Domains aktiv. Wählen Sie eine zum Freigeben aus sie wird deaktiviert und diese Seite stattdessen aktiviert.', 'gdpr-content-blocker' ); ?>
</p>
</td>
</tr>
</tbody></table>
<?php submit_button( __( 'Freigeben und diese Seite aktivieren', 'gdpr-content-blocker' ), 'primary' ); ?>
</form>
<!-- No free slots: list every bound domain with a trash button to free it. -->
<h2><?php esc_html_e( 'Belegte Domains', 'gdpr-content-blocker' ); ?></h2>
<p class="description" style="max-width:640px;">
<?php esc_html_e( 'Diese Lizenz ist bereits auf folgenden Domains aktiv. Entfernen Sie eine, um den Platz freizugeben diese Seite wird anschließend automatisch aktiviert.', 'gdpr-content-blocker' ); ?>
</p>
<ul class="cb-domain-list">
<?php
$confirm = esc_attr__( 'Diese Domain wirklich aus der Lizenz entfernen?', 'gdpr-content-blocker' );
foreach ( $lic['pending_domains'] as $d ) :
?>
<li>
<code><?php echo esc_html( $d ); ?></code>
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>"
onsubmit="return confirm('<?php echo $confirm; ?>');">
<?php wp_nonce_field( 'cb_license', 'cb_license_nonce' ); ?>
<input type="hidden" name="action" value="cb_license_swap">
<input type="hidden" name="cb_release_domain" value="<?php echo esc_attr( $d ); ?>">
<button type="submit" class="cb-remove-service"
aria-label="<?php esc_attr_e( 'Domain entfernen', 'gdpr-content-blocker' ); ?>"
title="<?php esc_attr_e( 'Domain entfernen', 'gdpr-content-blocker' ); ?>">
<span class="dashicons dashicons-trash"></span>
</button>
</form>
</li>
<?php endforeach; ?>
</ul>
<hr>
<?php endif; ?>

View File

@@ -466,6 +466,25 @@ class CB_Settings {
.cb-admin-wrap .cb-tab-content {
padding-top: 20px;
}
/* bound-domains list (license full) */
.cb-admin-wrap .cb-domain-list {
margin: 10px 0 0;
max-width: 480px;
}
.cb-admin-wrap .cb-domain-list li {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 8px 12px;
margin: 0 0 6px;
background: #fff;
border: 1px solid #dcdcde;
border-radius: 4px;
}
.cb-admin-wrap .cb-domain-list form {
margin: 0;
}
.cb-admin-wrap .cb-field label {
display: block;
font-weight: 600;

View File

@@ -57,14 +57,17 @@ msgstr "Status"
msgid "Domain"
msgstr "Domain"
msgid "Domain freigeben"
msgstr "Release domain"
msgid "Belegte Domains"
msgstr "Bound domains"
msgid "Diese Lizenz ist bereits auf den genannten Domains aktiv. Wählen Sie eine zum Freigeben aus sie wird deaktiviert und diese Seite stattdessen aktiviert."
msgstr "This license is already active on the domains listed. Choose one to release — it will be deactivated and this site activated instead."
msgid "Diese Lizenz ist bereits auf folgenden Domains aktiv. Entfernen Sie eine, um den Platz freizugeben diese Seite wird anschließend automatisch aktiviert."
msgstr "This license is already active on the following domains. Remove one to free a seat — this site will then be activated automatically."
msgid "Freigeben und diese Seite aktivieren"
msgstr "Release and activate this site"
msgid "Diese Domain wirklich aus der Lizenz entfernen?"
msgstr "Really remove this domain from the license?"
msgid "Domain entfernen"
msgstr "Remove domain"
msgid "Aus Sicherheitsgründen verdeckt. Zum Ändern bitte zuerst deaktivieren."
msgstr "Hidden for security. To change it, deactivate first."

View File

@@ -22,9 +22,10 @@ EN = [
"Not activated",
"Status",
"Domain",
"Release domain",
"This license is already active on the domains listed. Choose one to release — it will be deactivated and this site activated instead.",
"Release and activate this site",
"Bound domains",
"This license is already active on the following domains. Remove one to free a seat — this site will then be activated automatically.",
"Really remove this domain from the license?",
"Remove domain",
"Hidden for security. To change it, deactivate first.",
"Deactivate license",
"Try again",