Server : LiteSpeed
System : Linux terra.hostitbro.com 5.14.0-611.54.3.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 7 16:31:24 EDT 2026 x86_64
User : outerorb ( 1091)
PHP Version : 8.1.34
Disable Function : mail
Directory :  /home2/outerorb/assetradar.outerorbittech.com/admin/

📁 Create New:
⬆️ Upload File:
Current Dir [ Writable ] Root [ Writable ]


OR Upload from URL:
URL: Save as:

📄 File: master_data.php

Path: /home2/outerorb/assetradar.outerorbittech.com/admin/master_data.php

Size: 22.03 KB

Permissions: 0666

<?php
// admin/master_data.php
// Master Data Panel for Admins


require_once '../inc/auth.php';
define('ADMIN_PAGE', true);
require_once '../inc/header.php';
include __DIR__ . '/admin_menu.php';

// Only allow access for Admin users
if (!is_admin()) {
    header('Location: ../index.php');
    exit();
}
?>
<style>
    /* Page-specific styles (kept minimal — header.php provides Bootstrap) */
    .master-panel { max-width: 1100px; margin: 30px auto; background: #fff; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.07); padding: 24px; }
    .tab-bar { display: flex; gap: 8px; margin-bottom: 16px; }
    .tab { flex: 1; text-align: center; padding: 10px 0; background: #e3f2fd; cursor: pointer; border-radius: 6px 6px 0 0; font-weight: 500; transition: background 0.2s; border: none; outline: none; color: #333; }
    .tab.active { background: #4285f4; color: #fff; }
    .tab-content { background: #fff; border-radius: 0 0 8px 8px; box-shadow: 0 1px 4px rgba(0,0,0,0.04); padding: 18px; margin-top: -2px; }
    table { width: 100%; border-collapse: collapse; margin-top: 12px; background: #fff; border: 1px solid #e9ecef; }
    th, td { padding: 8px 10px; border-bottom: 1px solid #e9ecef; text-align: left; }
    th { background: #f8f9fa; font-weight: 600; }
    /* Ensure table bottom border is visible by styling last-row cells */
    tbody tr:last-child td { border-bottom: 1px solid #e9ecef; }
    form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 10px; }
    @media (max-width: 700px) { .master-panel { padding: 12px; } table, th, td { font-size: 13px; } }
</style>

<div class="master-panel">
    <h2 style="margin-bottom:12px; color:#4285f4;">Master Data Panel</h2>
    <div class="tab-bar" id="tabs">
        <button class="tab active" data-tab="roles">Roles</button>
        <button class="tab" data-tab="teams">Teams</button>
        <button class="tab" data-tab="categories">Categories</button>
        <button class="tab" data-tab="users">Users</button>
        <button class="tab" data-tab="items">Items</button>
        <button class="tab" data-tab="vendors">Vendors</button>
    </div>
    <div id="dynamic-buttons" style="margin-bottom:12px; display:flex; gap:8px;"></div>
    <div id="tab-contents">
        <div class="tab-content" id="roles-content">Loading...</div>
        <div class="tab-content" id="teams-content" style="display:none">Loading...</div>
        <div class="tab-content" id="categories-content" style="display:none">Loading...</div>
        <div class="tab-content" id="users-content" style="display:none">Loading...</div>
        <div class="tab-content" id="items-content" style="display:none;"><div style="overflow-x:auto;">Loading...</div></div>
        <div class="tab-content" id="vendors-content" style="display:none">Loading...</div>
    </div>
</div>

<script>
        // Simple tab switching
        const tabs = document.querySelectorAll('.tab');
        const contents = document.querySelectorAll('.tab-content');
        tabs.forEach(tab => {
            tab.addEventListener('click', () => {
                tabs.forEach(t => t.classList.remove('active'));
                tab.classList.add('active');
                contents.forEach(c => c.style.display = 'none');
                const tabName = tab.dataset.tab;
                document.getElementById(tabName + '-content').style.display = 'block';
                loadEntity(tabName);
                setDynamicButtons(tabName);
            });
        });

        // Load entity data via AJAX
        function loadEntity(entity) {
            const contentId = entity + '-content';
            document.getElementById(contentId).innerHTML = 'Loading...';
                fetch('master_data_api.php?entity=' + entity + '&action=list')
                    .then(res => res.json())
                    .then(data => {
                        let html = '';
                        // Add form for new entry (now above table)
                        html += `<h4>Add New</h4><form onsubmit=\"return addRow('${entity}', this)\">`;
                        if (entity === 'roles') {
                            html += 'Name: <input name="name" required> Slug: <input name="slug" required> <button type="submit">Add</button>';
                        } else if (entity === 'teams' || entity === 'categories') {
                            html += 'Name: <input name="name" required> <button type="submit">Add</button>';
                        } else if (entity === 'users') {
                            html += 'Name: <input name="name" required> Email: <input name="email" required> Password: <input name="password" required><br>';
                            html += '<div style="display:flex;align-items:center;gap:16px;margin-top:8px;margin-bottom:8px;">';
                            html += '<label for="role-slug-select" style="font-weight:500;">Role</label> <select name="role_slug" required id="role-slug-select" style="width:180px;"><option value="">Loading...</option></select>';
                            html += '<label for="team-select" style="font-weight:500;">Team</label> <select name="team_id" id="team-select" style="width:180px;"><option value="">Loading...</option></select>';
                            html += '<button type="submit">Add</button>';
                            html += '</div>';
                        } else if (entity === 'items') {
                            html += 'Asset Tag: <input name="asset_tag" required> Item Name: <input name="item_name" required> Category ID: <input name="category_id" required> Brand/Model: <input name="brand_model"> Serial Number: <input name="serial_number"> Purchase Date: <input name="purchase_date" type="date"> Warranty To: <input name="warranty_to" type="date"> Assigned To (User ID): <input name="assigned_to"> Condition Status: <input name="condition_status"> <button type="submit">Add</button>';
                        } else if (entity === 'vendors') {
                            html += 'Name: <input name="name" required> Contact: <input name="contact_info"> Address: <input name="address"> Email: <input name="email"> Phone: <input name="phone"> Notes: <input name="notes"> <button type="submit">Add</button>';
                        }
                        html += '</form>';
                        // Edit form placeholder
                        html += `<div id=\"edit-form-${entity}\" style=\"display:none;\"></div>`;
                        // Data table
                        if (Array.isArray(data)) {
                            if (entity === 'items') {
                                html += '<div style="overflow-x:auto">';
                            }
                            html += '<table border="1" cellpadding="6"><tr>';
                            if (data.length > 0) {
                                if (entity === 'vendors') {
                                    Object.keys(data[0]).forEach(k => {
                                        html += '<th>' + k + '</th>';
                                    });
                                } else {
                                    // Table headers
                                    if (entity === 'users') {
                                        // Show all columns except team_id, team_name, role_id, role_slug, created_at, deleted, api_token. Add Role and Team columns.
                                        Object.keys(data[0]).forEach(k => {
                                            if (k !== 'team_id' && k !== 'team_name' && k !== 'role_id' && k !== 'role_slug' && k !== 'created_at' && k !== 'deleted' && k !== 'api_token') {
                                                html += '<th>' + k + '</th>';
                                            }
                                        });
                                        html += '<th>Role</th><th>Team</th>';
                                    } else {
                                        Object.keys(data[0]).forEach(k => {
                                            html += '<th>' + k + '</th>';
                                        });
                                    }
                                }
                                html += '<th>Actions</th></tr>';
                                // Table rows
                                data.forEach(row => {
                                    html += '<tr>';
                                    if (entity === 'users') {
                                        Object.entries(row).forEach(([k, v]) => {
                                            if (k !== 'team_id' && k !== 'team_name' && k !== 'role_id' && k !== 'role_slug' && k !== 'created_at' && k !== 'deleted' && k !== 'api_token') {
                                                html += '<td>' + v + '</td>';
                                            }
                                        });
                                        html += '<td>' + (row.role_name || '') + '</td>';
                                        html += '<td>' + (row.team_name || '') + '</td>';
                                    } else if (entity === 'vendors') {
                                        Object.entries(row).forEach(([k, v]) => {
                                            html += '<td>' + v + '</td>';
                                        });
                                    } else {
                                        Object.entries(row).forEach(([k, v]) => {
                                            html += '<td>' + v + '</td>';
                                        });
                                    }
                                    if (entity === 'roles') {
                                        html += `<td><button title="Edit" onclick=\"editRow('${entity}', ${row.id}, '${escapeQuotes(row.name ?? '')}', '${escapeQuotes(row.slug ?? '')}')\" style="background:none;border:none;padding:4px 8px;font-size:18px;cursor:pointer;">✏️</button> <button title="Delete" onclick=\"deleteRow('${entity}', ${row.id})\" style="background:none;border:none;padding:4px 8px;font-size:18px;cursor:pointer;">🗑️</button></td>`;
                                    } else if (entity === 'teams' || entity === 'categories') {
                                        html += `<td><button title="Edit" onclick=\"editRow('${entity}', ${row.id}, '${escapeQuotes(row.name ?? '')}')\" style="background:none;border:none;padding:4px 8px;font-size:18px;cursor:pointer;">✏️</button> <button title="Delete" onclick=\"deleteRow('${entity}', ${row.id})\" style="background:none;border:none;padding:4px 8px;font-size:18px;cursor:pointer;">🗑️</button></td>`;
                                    } else if (entity === 'users') {
                                        html += `<td><button title="Edit" onclick=\"editRow('${entity}', ${row.id}, '${escapeQuotes(row.name ?? '')}', '${escapeQuotes(row.email ?? '')}', '${escapeQuotes(row.role_slug ?? '')}', ${row.team_id})\" style="background:none;border:none;padding:4px 8px;font-size:18px;cursor:pointer;">✏️</button> <button title="Delete" onclick=\"deleteRow('${entity}', ${row.id})\" style="background:none;border:none;padding:4px 8px;font-size:18px;cursor:pointer;">🗑️</button></td>`;
                                    } else if (entity === 'items') {
                                        html += `<td><button title="Edit" onclick=\"editRow('${entity}', ${row.id}, '${escapeQuotes(row.asset_tag ?? '')}', '${escapeQuotes(row.item_name ?? '')}', ${row.category_id}, '${escapeQuotes(row.brand_model ?? '')}', '${escapeQuotes(row.serial_number ?? '')}', '${row.purchase_date ?? ''}', '${row.warranty_to ?? ''}', ${row.assigned_to ?? 0}, '${escapeQuotes(row.condition_status ?? '')}')\" style="background:none;border:none;padding:4px 8px;font-size:18px;cursor:pointer;">✏️</button> <button title="Delete" onclick=\"deleteRow('${entity}', ${row.id})\" style="background:none;border:none;padding:4px 8px;font-size:18px;cursor:pointer;">🗑️</button></td>`;
                                    } else if (entity === 'vendors') {
                                        html += `<td><button title="Edit" onclick="editRow('vendors', ${row.id}, '${escapeQuotes(row.name ?? '')}', '${escapeQuotes(row.contact_info ?? '')}', '${escapeQuotes(row.address ?? '')}', '${escapeQuotes(row.email ?? '')}', '${escapeQuotes(row.phone ?? '')}', '${escapeQuotes(row.notes ?? '')}')" style="background:none;border:none;padding:4px 8px;font-size:18px;cursor:pointer;">✏️</button> <button title="Delete" onclick="deleteRow('vendors', ${row.id})" style="background:none;border:none;padding:4px 8px;font-size:18px;cursor:pointer;">🗑️</button></td>`;
                                    }
                                    html += '</tr>';
                                });
                            } else {
                                html += '<td>No data found</td></tr>';
                            }
                            html += '</table>';
                            if (entity === 'items') {
                                html += '</div>';
                            }
                        } else {
                            html += '<span style="color:red">Error loading data</span>';
                        }
                        document.getElementById(contentId).innerHTML = html;
                    })
                    .catch(() => {
                        document.getElementById(contentId).innerHTML = '<span style="color:red">Error loading data</span>';
                    });
        }

        // Helper to escape quotes in JS
        function escapeQuotes(str) {
            return String(str).replace(/'/g, "&#39;").replace(/"/g, "&quot;");
        }

        // Add new row
        window.addRow = function(entity, form) {
            const fd = new FormData(form);
            fetch('master_data_api.php?entity=' + entity + '&action=create', {
                method: 'POST',
                body: fd
            }).then(res => res.json()).then(() => {
                loadEntity(entity);
            });
            return false;
        }

        // Edit row
        window.editRow = function(entity, ...args) {
            let html = `<h4>Edit</h4><form onsubmit="return updateRow('${entity}', ${args[0]}, this)">`;
            if (entity === 'roles') {
                html += `Name: <input name="name" value="${args[1]}" required> Slug: <input name="slug" value="${args[2]}" required> <button type="submit">Update</button>`;
            } else if (entity === 'teams' || entity === 'categories') {
                html += `Name: <input name="name" value="${args[1]}" required> <button type="submit">Update</button>`;
            } else if (entity === 'users') {
                                // Fetch roles and teams for dropdowns
                                Promise.all([
                                    fetch('master_data_api.php?entity=roles&action=list').then(res => res.json()),
                                    fetch('master_data_api.php?entity=teams&action=list').then(res => res.json())
                                ]).then(([roles, teams]) => {
                                    let roleOptions = '';
                                    roles.forEach(r => {
                                        roleOptions += `<option value="${r.slug}"${r.slug==args[3]?' selected':''}>${r.name}</option>`;
                                    });
                                    let teamOptions = '<option value="">None</option>';
                                    teams.forEach(t => {
                                        teamOptions += `<option value="${t.id}"${t.id==args[4]?' selected':''}>${t.name}</option>`;
                                    });
                                    html += `Name: <input name="name" value="${args[1]}" required> Email: <input name="email" value="${args[2]}" required> Role: <select name="role_slug">${roleOptions}</select> Team: <select name="team_id">${teamOptions}</select> Password: <input name="password" placeholder="Leave blank to keep unchanged"> <button type="submit">Update</button>`;
                                    html += '</form> <button onclick="cancelEdit(\'' + entity + '\')">Cancel</button>';
                                    document.getElementById('edit-form-' + entity).innerHTML = html;
                                    document.getElementById('edit-form-' + entity).style.display = 'block';
                                });
                                return;
            } else if (entity === 'vendors') {
                html += `<h4>Edit</h4><form onsubmit="return updateRow('vendors', ${args[0]}, this)">Name: <input name='name' value='${args[1]}' required> Contact: <input name='contact_info' value='${args[2]}'> Address: <input name='address' value='${args[3]}'> Email: <input name='email' value='${args[4]}'> Phone: <input name='phone' value='${args[5]}'> Notes: <input name='notes' value='${args[6]}'> <button type='submit'>Update</button></form> <button onclick="cancelEdit('vendors')">Cancel</button>`;
            }
            html += '</form> <button onclick="cancelEdit(\'' + entity + '\')">Cancel</button>';
            document.getElementById('edit-form-' + entity).innerHTML = html;
            document.getElementById('edit-form-' + entity).style.display = 'block';
        }

        window.cancelEdit = function(entity) {
            document.getElementById('edit-form-' + entity).style.display = 'none';
        }

        // Update row
        window.updateRow = function(entity, id, form) {
            const fd = new FormData(form);
            fd.append('id', id);
            fetch('master_data_api.php?entity=' + entity + '&action=update', {
                method: 'POST',
                body: fd
            }).then(res => res.json()).then(() => {
                loadEntity(entity);
            });
            return false;
        }

        // Delete row
        window.deleteRow = function(entity, id) {
            if (!confirm('Are you sure you want to delete this entry?')) return;
            const fd = new FormData();
            fd.append('id', id);
            fetch('master_data_api.php?entity=' + entity + '&action=delete', {
                method: 'POST',
                body: fd
            }).then(res => res.json()).then(() => {
                loadEntity(entity);
            });
        }

        // After loadEntity, fetch roles and teams for user form dropdowns
        function fetchRolesAndTeams() {
            fetch('master_data_api.php?entity=roles&action=list')
                .then(res => res.json())
                .then(roles => {
                    let roleOptions = '';
                    roles.forEach(r => {
                        roleOptions += `<option value="${r.slug}">${r.name}</option>`;
                    });
                    const roleSlugSelect = document.getElementById('role-slug-select');
                    if (roleSlugSelect) roleSlugSelect.innerHTML = roleOptions;
                });
            fetch('master_data_api.php?entity=teams&action=list')
                .then(res => res.json())
                .then(teams => {
                    let teamOptions = '<option value="">None</option>';
                    teams.forEach(t => {
                        teamOptions += `<option value="${t.id}">${t.name}</option>`;
                    });
                    const teamSelect = document.getElementById('team-select');
                    if (teamSelect) teamSelect.innerHTML = teamOptions;
                });
        }
        // Patch loadEntity to call fetchRolesAndTeams for users
        const origLoadEntity = loadEntity;
            loadEntity = function(entity) {
                origLoadEntity(entity);
                if (entity === 'users') {
                    // Use MutationObserver to wait for dropdown to appear, then populate
                    const observer = new MutationObserver(() => {
                        const roleSelect = document.getElementById('role-slug-select');
                        const teamSelect = document.getElementById('team-select');
                        if (roleSelect && teamSelect) {
                            fetchRolesAndTeams();
                            observer.disconnect();
                        }
                    });
                    observer.observe(document.getElementById('users-content'), { childList: true, subtree: true });
                }
            }

        function setDynamicButtons(tabName) {
            const btns = document.getElementById('dynamic-buttons');
            let label = tabName.charAt(0).toUpperCase() + tabName.slice(1);
            btns.innerHTML = `<button onclick=\"exportSingle('${tabName}')\" style=\"background:#43b581; color:#fff; border:none; padding:8px 18px; border-radius:4px; font-weight:500;\">Export ${label}</button> <label style=\"background:#4285f4; color:#fff; border:none; padding:8px 18px; border-radius:4px; font-weight:500; cursor:pointer;\">Import ${label}<input type=\"file\" style=\"display:none;\" onchange=\"importSingle('${tabName}', this.files[0])\"></label>`;
        }
        function exportSingle(entity) {
            window.location = 'master_data_api.php?entity=' + entity + '&action=export';
        }
        function importSingle(entity, file) {
            if (!file) return;
            const fd = new FormData();
            fd.append('file', file);
            fetch('master_data_api.php?entity=' + entity + '&action=import', {
                method: 'POST',
                body: fd
            }).then(res => res.json()).then(data => {
                if (data.success) {
                    alert('Import successful!');
                    loadEntity(entity);
                } else {
                    alert('Import failed: ' + (data.error || 'Unknown error'));
                }
            });
        }
        // Initial load
        setDynamicButtons('roles');
        loadEntity('roles');
    </script>
</body>
</html>
<?php
require_once '../inc/footer.php';
?>


← Back to Directory Edit File 🔒 Chmod

WP File Manager