296 lines
9.9 KiB
JavaScript
296 lines
9.9 KiB
JavaScript
/**
|
|
* DeComPress CMS - Core Admin Logic
|
|
*/
|
|
|
|
const state = {
|
|
currentView: 'Pages',
|
|
themes: [
|
|
{
|
|
id: 1,
|
|
name: 'Minimalist',
|
|
version: '1.2.0',
|
|
active: true,
|
|
color: 'bg-slate-300'
|
|
},
|
|
{
|
|
id: 2,
|
|
name: 'Dark Mode Pro',
|
|
version: '2.0.1',
|
|
active: false,
|
|
color: 'bg-gray-800'
|
|
},
|
|
{
|
|
id: 3,
|
|
name: 'Ocean Breeze',
|
|
version: '1.0.5',
|
|
active: false,
|
|
color: 'bg-blue-400'
|
|
}
|
|
],
|
|
customFields: [], // Dynamic state for the field builder
|
|
navItems: [
|
|
{ name: 'Pages', icon: '📄' },
|
|
{ name: 'Themes', icon: '🎨' },
|
|
{ name: 'Post Types', icon: '📌' },
|
|
{ name: 'Custom Fields', icon: '🔧' },
|
|
{ name: 'Users', icon: '👥' },
|
|
{ name: 'Roles', icon: '🛡️' },
|
|
{ name: 'Permissions', icon: '🔑' }
|
|
]
|
|
}
|
|
|
|
// --- Initialization ---
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
initApp()
|
|
})
|
|
|
|
function initApp () {
|
|
renderNav()
|
|
navigateTo(state.currentView)
|
|
|
|
// Mobile Toggle Logic
|
|
document.getElementById('mobile-toggle').addEventListener('click', () => {
|
|
const sidebar = document.getElementById('sidebar')
|
|
sidebar.classList.toggle('hidden')
|
|
sidebar.classList.toggle('absolute')
|
|
sidebar.classList.toggle('z-50')
|
|
sidebar.classList.toggle('h-full')
|
|
})
|
|
}
|
|
|
|
// --- Router ---
|
|
function navigateTo (viewName) {
|
|
state.currentView = viewName
|
|
document.getElementById('view-title').innerText = viewName
|
|
renderNav() // Refresh active state
|
|
|
|
const container = document.getElementById('app-content')
|
|
container.innerHTML = '' // Clear current
|
|
|
|
switch (viewName) {
|
|
case 'Pages':
|
|
container.innerHTML = viewPages()
|
|
break
|
|
case 'Themes':
|
|
container.innerHTML = viewThemes()
|
|
break
|
|
case 'Permissions':
|
|
container.innerHTML = viewPermissions()
|
|
break
|
|
case 'Custom Fields':
|
|
container.innerHTML = viewCustomFields()
|
|
break
|
|
case 'Users':
|
|
container.innerHTML = viewUsers()
|
|
break
|
|
default:
|
|
container.innerHTML = `<div class="p-10 text-center border-2 border-dashed rounded-lg text-gray-400">
|
|
${viewName} module is currently under construction.
|
|
</div>`
|
|
}
|
|
}
|
|
|
|
// --- Views ---
|
|
|
|
function viewPages () {
|
|
return `
|
|
<div class="bg-white rounded-xl shadow-sm border border-gray-200">
|
|
<table class="w-full text-left">
|
|
<thead class="bg-gray-50 border-b border-gray-200">
|
|
<tr>
|
|
<th class="p-4 font-semibold text-gray-600">Page Title</th>
|
|
<th class="p-4 font-semibold text-gray-600">Status</th>
|
|
<th class="p-4 font-semibold text-gray-600 text-right">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-100">
|
|
<tr><td class="p-4">Homepage</td><td class="p-4"><span class="bg-green-100 text-green-700 px-2 py-1 rounded text-xs">Published</span></td><td class="p-4 text-right text-blue-600 cursor-pointer">Edit</td></tr>
|
|
<tr><td class="p-4">Contact</td><td class="p-4"><span class="bg-yellow-100 text-yellow-700 px-2 py-1 rounded text-xs">Draft</span></td><td class="p-4 text-right text-blue-600 cursor-pointer">Edit</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
`
|
|
}
|
|
|
|
function viewThemes () {
|
|
return `
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
${state.themes
|
|
.map(
|
|
t => `
|
|
<div class="bg-white rounded-xl shadow-sm border-2 ${
|
|
t.active ? 'border-blue-500' : 'border-transparent'
|
|
} overflow-hidden">
|
|
<div class="h-32 ${t.color}"></div>
|
|
<div class="p-4">
|
|
<h4 class="font-bold">${t.name}</h4>
|
|
<p class="text-xs text-gray-500 mb-4">Version ${
|
|
t.version
|
|
}</p>
|
|
<button onclick="handleAction('Theme ${
|
|
t.name
|
|
} activated')" class="w-full py-2 rounded text-sm font-medium ${
|
|
t.active
|
|
? 'bg-blue-50 text-blue-600'
|
|
: 'bg-gray-100 hover:bg-gray-200 text-gray-700'
|
|
}">
|
|
${t.active ? 'Active' : 'Activate'}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
`
|
|
)
|
|
.join('')}
|
|
</div>
|
|
`
|
|
}
|
|
|
|
function viewPermissions () {
|
|
const roles = ['Admin', 'Editor', 'Subscriber']
|
|
const caps = ['Update Core', 'Manage Themes', 'Delete Posts', 'Write Posts']
|
|
return `
|
|
<div class="bg-white rounded-xl shadow-sm overflow-hidden border border-gray-200">
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full text-left">
|
|
<thead class="bg-gray-50 border-b border-gray-200">
|
|
<tr>
|
|
<th class="p-4 text-gray-600">Capability</th>
|
|
${roles
|
|
.map(
|
|
r =>
|
|
`<th class="p-4 text-center text-gray-600">${r}</th>`
|
|
)
|
|
.join('')}
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-100">
|
|
${caps
|
|
.map(
|
|
c => `
|
|
<tr>
|
|
<td class="p-4 font-medium">${c}</td>
|
|
${roles
|
|
.map(
|
|
r =>
|
|
`<td class="p-4 text-center"><input type="checkbox" ${
|
|
r === 'Admin' ? 'checked' : ''
|
|
} class="w-4 h-4 rounded border-gray-300"></td>`
|
|
)
|
|
.join('')}
|
|
</tr>
|
|
`
|
|
)
|
|
.join('')}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
`
|
|
}
|
|
|
|
function viewCustomFields () {
|
|
return `
|
|
<div class="max-w-4xl mx-auto">
|
|
<div class="flex justify-between items-center mb-6">
|
|
<h3 class="text-lg font-bold">Field Group: Blog Metadata</h3>
|
|
<button onclick="addField()" class="bg-blue-600 text-white px-4 py-2 rounded-lg text-sm hover:bg-blue-700 transition">+ Add Field</button>
|
|
</div>
|
|
<div id="fields-container" class="space-y-4">
|
|
${
|
|
state.customFields.length === 0
|
|
? '<p class="text-gray-400 italic text-center py-10">No fields added yet. Click "+ Add Field" to begin.</p>'
|
|
: ''
|
|
}
|
|
</div>
|
|
</div>
|
|
`
|
|
}
|
|
|
|
function viewUsers () {
|
|
return `
|
|
<div class="bg-white p-6 rounded-xl shadow-sm max-w-lg border border-gray-200">
|
|
<h3 class="font-bold mb-4">Invite New User</h3>
|
|
<div class="space-y-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700">Email Address</label>
|
|
<input type="email" id="u-email" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm border p-2 focus:ring-blue-500 focus:border-blue-500">
|
|
</div>
|
|
<button onclick="handleUserInvite()" class="bg-slate-900 text-white w-full py-2 rounded-md font-medium hover:bg-black transition">Send Invitation</button>
|
|
</div>
|
|
</div>
|
|
`
|
|
}
|
|
|
|
// --- Component Logic ---
|
|
|
|
function renderNav () {
|
|
const nav = document.getElementById('main-nav')
|
|
nav.innerHTML = state.navItems
|
|
.map(
|
|
item => `
|
|
<button onclick="navigateTo('${item.name}')"
|
|
class="w-full flex items-center px-4 py-3 rounded-lg text-sm transition-colors ${
|
|
state.currentView === item.name
|
|
? 'bg-blue-600 text-white shadow-lg shadow-blue-900/20'
|
|
: 'text-gray-400 hover:bg-slate-800 hover:text-white'
|
|
}">
|
|
<span class="mr-3 text-lg">${item.icon}</span>
|
|
<span class="font-medium">${item.name}</span>
|
|
</button>
|
|
`
|
|
)
|
|
.join('')
|
|
}
|
|
|
|
function addField () {
|
|
const id = Date.now()
|
|
state.customFields.push({ id, label: '', type: 'text' })
|
|
refreshFields()
|
|
}
|
|
|
|
function removeField (id) {
|
|
state.customFields = state.customFields.filter(f => f.id !== id)
|
|
refreshFields()
|
|
}
|
|
|
|
function refreshFields () {
|
|
const container = document.getElementById('fields-container')
|
|
if (!container) return
|
|
|
|
container.innerHTML = state.customFields
|
|
.map(
|
|
(field, index) => `
|
|
<div class="bg-white p-4 rounded-lg border border-gray-200 shadow-sm flex items-center space-x-4 animate-in fade-in duration-300">
|
|
<div class="text-gray-300 cursor-move">☰</div>
|
|
<div class="flex-1 grid grid-cols-2 gap-4">
|
|
<input type="text" placeholder="Field Label" class="border rounded p-2 text-sm" value="${field.label}">
|
|
<select class="border rounded p-2 text-sm">
|
|
<option>Text</option>
|
|
<option>Textarea</option>
|
|
<option>Image</option>
|
|
<option>Boolean (Toggle)</option>
|
|
</select>
|
|
</div>
|
|
<button onclick="removeField(${field.id})" class="text-red-400 hover:text-red-600 p-2">✕</button>
|
|
</div>
|
|
`
|
|
)
|
|
.join('')
|
|
}
|
|
|
|
// --- General Handlers ---
|
|
|
|
function handleUserInvite () {
|
|
const email = document.getElementById('u-email').value
|
|
if (!email.includes('@')) {
|
|
alert('Please enter a valid email address.')
|
|
return
|
|
}
|
|
alert(`Invitation sent to ${email}`)
|
|
}
|
|
|
|
function handleAction (msg) {
|
|
console.log('CMS Action:', msg)
|
|
alert(msg)
|
|
}
|