Add free/paid feature gating (Role Editor, Activity Log, DB Explorer,
Analytics, White Label, remote site switcher are paid) - New License class is the single gate every paid feature checks — today it's a placeholder (any non-empty license_key counts as active) since there's no license server yet, but every gated feature already funnels through it so swapping in real remote validation later won't touch anything else. - Role Editor, Activity Log, and Database Explorer stay registered/ capability-checked as before, but render an UpgradeNotice screen instead of the real feature when unlicensed (and skip loading the real JS bundle/REST data). Menu Creator, Admin Notices, Comments, and Plugins stay free. - Analytics' tracking hooks and REST endpoint, and White Label's favicon/rename/text-replace hooks, simply don't register without a license. Settings fields for both stay visible/editable either way. - Remote site switcher gated alongside its existing capability check. - Sidebar shows a small lock badge on locked Aurora nav items; the Dashboard's Analytics tab shows the same upgrade prompt when locked. - Fixed an unrelated bug surfaced while testing Role Editor: RolesData's REST callback called get_editable_roles() without loading wp-admin/includes/user.php first, which REST requests don't get for free (only real wp-admin page loads do) — 500'd every time. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
73591e0ca4
commit
6d502604d7
@@ -0,0 +1,10 @@
|
||||
import { createApp } from 'vue';
|
||||
import '@/shell/shell-frame.css';
|
||||
import UpgradeNotice from '@/pages/_shared/UpgradeNotice.vue';
|
||||
|
||||
const mountEl = document.querySelector('[data-aurora-locked-feature]');
|
||||
|
||||
if (mountEl) {
|
||||
const data = JSON.parse(mountEl.dataset.auroraLockedFeature || '{}');
|
||||
createApp(UpgradeNotice, { feature: data.feature, description: data.description }).mount(mountEl);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<script setup>
|
||||
defineProps({
|
||||
feature: { type: String, required: true },
|
||||
description: { type: String, default: '' },
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="upgrade-notice">
|
||||
<div class="upgrade-notice__card">
|
||||
<span class="upgrade-notice__icon">
|
||||
<span class="dashicons dashicons-lock" />
|
||||
</span>
|
||||
<h1 class="upgrade-notice__title">{{ feature }} is a Pro feature</h1>
|
||||
<p class="upgrade-notice__text">
|
||||
{{ description || `Upgrade to Aurora Admin Pro to unlock ${feature}.` }}
|
||||
</p>
|
||||
<a class="upgrade-notice__cta" href="admin.php?page=aurora-admin#license">
|
||||
Enter a license key
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.upgrade-notice {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 400px;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
.upgrade-notice__card {
|
||||
max-width: 380px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.upgrade-notice__icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--aurora-accent-soft);
|
||||
color: var(--aurora-accent);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.upgrade-notice__icon .dashicons {
|
||||
font-size: 26px;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
}
|
||||
.upgrade-notice__title {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
color: var(--aurora-text);
|
||||
}
|
||||
.upgrade-notice__text {
|
||||
font-size: 0.875rem;
|
||||
color: var(--aurora-text-muted);
|
||||
margin: 0;
|
||||
}
|
||||
.upgrade-notice__cta {
|
||||
margin-top: 8px;
|
||||
padding: 8px 18px;
|
||||
border-radius: 8px;
|
||||
background: var(--aurora-accent);
|
||||
color: var(--aurora-accent-text);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
}
|
||||
.upgrade-notice__cta:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
||||
@@ -13,13 +13,14 @@ import ActiveUsers from './cards/ActiveUsers.vue';
|
||||
import DeviceUsage from './cards/DeviceUsage.vue';
|
||||
import Engagement from './cards/Engagement.vue';
|
||||
import TopList from './cards/TopList.vue';
|
||||
import UpgradeNotice from '../_shared/UpgradeNotice.vue';
|
||||
|
||||
const props = defineProps({
|
||||
serverData: { type: Object, required: true },
|
||||
});
|
||||
|
||||
const { data, loading, load } = useDashboardData(props.serverData);
|
||||
const { data: analytics, load: loadAnalytics } = useAnalyticsData(props.serverData);
|
||||
const { data: analytics, error: analyticsError, load: loadAnalytics } = useAnalyticsData(props.serverData);
|
||||
|
||||
// Date range — default last 7 days, with simple presets.
|
||||
const today = new Date();
|
||||
@@ -107,6 +108,12 @@ onMounted(() => reload(range.value[0], range.value[1]));
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<UpgradeNotice
|
||||
v-else-if="analyticsError"
|
||||
feature="Analytics"
|
||||
description="Upgrade to Aurora Admin Pro to unlock first-party visitor analytics for this dashboard."
|
||||
/>
|
||||
|
||||
<div v-else class="dash__grid">
|
||||
<div class="dash__cell" style="grid-column: span 8">
|
||||
<PageViews :data="analytics ? analytics.pageViews : {}" />
|
||||
|
||||
@@ -91,7 +91,7 @@ const openFontList = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="field">
|
||||
<div class="field" :id="field.key === 'license_key' ? 'license' : null">
|
||||
<div class="field__info">
|
||||
<div class="field__label">{{ field.label }}</div>
|
||||
<p v-if="field.description" class="field__desc">{{ field.description }}</p>
|
||||
|
||||
@@ -42,7 +42,7 @@ export const settingsCategories = [
|
||||
type: 'text',
|
||||
label: 'Remote Site Switcher Capability',
|
||||
description:
|
||||
'WordPress capability required to see the remote site switcher in the toolbar. Defaults to "manage_options" (admin users). Users with this capability or below will see the switcher.',
|
||||
'Pro feature — requires a license. WordPress capability required to see the remote site switcher in the toolbar. Defaults to "manage_options" (admin users). Users with this capability or below will see the switcher.',
|
||||
placeholder: 'manage_options',
|
||||
},
|
||||
{
|
||||
@@ -111,7 +111,7 @@ export const settingsCategories = [
|
||||
{
|
||||
id: 'whitelabel',
|
||||
title: 'White Label',
|
||||
subtitle: 'Rebrand and customize interface text and icons',
|
||||
subtitle: 'Rebrand and customize interface text and icons (Pro feature — requires a license)',
|
||||
icon: 'dashicons-tag',
|
||||
fields: [
|
||||
{
|
||||
@@ -198,7 +198,7 @@ export const settingsCategories = [
|
||||
{
|
||||
id: 'analytics',
|
||||
title: 'Analytics',
|
||||
subtitle: 'Built-in analytics and tracking settings',
|
||||
subtitle: 'Built-in analytics and tracking settings (Pro feature — requires a license)',
|
||||
icon: 'dashicons-chart-bar',
|
||||
fields: [
|
||||
{
|
||||
|
||||
@@ -185,6 +185,9 @@ const isAuroraActive = (item) => normalize(item.url) === current.value;
|
||||
:class="{ 'sidebar__sublink--active': isAuroraActive(item) }"
|
||||
>
|
||||
{{ item.title }}
|
||||
<span v-if="item.locked" class="sidebar__pro-badge" title="Pro feature">
|
||||
<span class="dashicons dashicons-lock" />
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -382,6 +385,18 @@ const isAuroraActive = (item) => normalize(item.url) === current.value;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sidebar__pro-badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--aurora-text-muted);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.sidebar__pro-badge .dashicons {
|
||||
font-size: 13px;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
/* --- Aurora branded nav (right under the native menu's own divider) ---- */
|
||||
.sidebar__aurora {
|
||||
padding-bottom: 4px;
|
||||
|
||||
Reference in New Issue
Block a user