Skip to content

Html file Script for ITSM Tool

Ayushi-srivastav edited this page Oct 15, 2026 · 1 revision
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Local ITSM Tool</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
            background: #f4f4f4;
            color: #333;
        }

        .header {
            background: #2c3e50;
            color: white;
            padding: 1rem 2rem;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        .header h1 {
            font-size: 1.5rem;
            font-weight: 500;
        }

        .nav {
            background: #34495e;
            padding: 0.5rem 2rem;
            display: flex;
            gap: 1rem;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        .nav button {
            background: transparent;
            color: white;
            border: none;
            padding: 0.75rem 1.5rem;
            cursor: pointer;
            font-size: 0.95rem;
            border-radius: 4px;
            transition: background 0.3s;
        }

        .nav button:hover {
            background: rgba(255,255,255,0.1);
        }

        .nav button.active {
            background: #3498db;
        }

        .container {
            max-width: 1400px;
            margin: 2rem auto;
            padding: 0 2rem;
        }

        .actions {
            display: flex;
            gap: 1rem;
            margin-bottom: 1.5rem;
        }

        .btn {
            padding: 0.75rem 1.5rem;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 0.95rem;
            transition: all 0.3s;
            font-weight: 500;
        }

        .btn-primary {
            background: #3498db;
            color: white;
        }

        .btn-primary:hover {
            background: #2980b9;
        }

        .btn-secondary {
            background: #95a5a6;
            color: white;
        }

        .btn-secondary:hover {
            background: #7f8c8d;
        }

        .btn-success {
            background: #27ae60;
            color: white;
        }

        .btn-success:hover {
            background: #229954;
        }

        .card {
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            overflow: hidden;
        }

        .card-header {
            background: #ecf0f1;
            padding: 1rem 1.5rem;
            border-bottom: 1px solid #ddd;
            font-weight: 600;
            font-size: 1.1rem;
        }

        .card-body {
            padding: 1.5rem;
        }

        table {
            width: 100%;
            border-collapse: collapse;
        }

        th {
            background: #ecf0f1;
            padding: 0.75rem;
            text-align: left;
            font-weight: 600;
            border-bottom: 2px solid #bdc3c7;
        }

        td {
            padding: 0.75rem;
            border-bottom: 1px solid #ecf0f1;
        }

        tr:hover {
            background: #f8f9fa;
        }

        .badge {
            padding: 0.25rem 0.75rem;
            border-radius: 12px;
            font-size: 0.85rem;
            font-weight: 500;
            display: inline-block;
        }

        .badge-new { background: #3498db; color: white; }
        .badge-inprogress { background: #f39c12; color: white; }
        .badge-resolved { background: #27ae60; color: white; }
        .badge-closed { background: #95a5a6; color: white; }
        .badge-pending { background: #e67e22; color: white; }
        .badge-approved { background: #27ae60; color: white; }
        .badge-rejected { background: #e74c3c; color: white; }
        .badge-draft { background: #95a5a6; color: white; }
        .badge-scheduled { background: #9b59b6; color: white; }
        .badge-implemented { background: #16a085; color: white; }

        .priority-critical { color: #e74c3c; font-weight: 600; }
        .priority-high { color: #e67e22; font-weight: 600; }
        .priority-medium { color: #f39c12; font-weight: 600; }
        .priority-low { color: #27ae60; font-weight: 600; }

        .modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.5);
            z-index: 1000;
            overflow-y: auto;
        }

        .modal.active {
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 2rem;
        }

        .modal-content {
            background: white;
            border-radius: 8px;
            width: 100%;
            max-width: 800px;
            max-height: 90vh;
            overflow-y: auto;
        }

        .modal-header {
            padding: 1.5rem;
            border-bottom: 1px solid #ecf0f1;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .modal-header h2 {
            font-size: 1.5rem;
            font-weight: 600;
        }

        .modal-body {
            padding: 1.5rem;
        }

        .modal-footer {
            padding: 1.5rem;
            border-top: 1px solid #ecf0f1;
            display: flex;
            justify-content: flex-end;
            gap: 1rem;
        }

        .close-btn {
            background: none;
            border: none;
            font-size: 1.5rem;
            cursor: pointer;
            color: #7f8c8d;
        }

        .close-btn:hover {
            color: #2c3e50;
        }

        .form-group {
            margin-bottom: 1.5rem;
        }

        .form-group label {
            display: block;
            margin-bottom: 0.5rem;
            font-weight: 500;
            color: #2c3e50;
        }

        .form-group input,
        .form-group select,
        .form-group textarea {
            width: 100%;
            padding: 0.75rem;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 0.95rem;
            font-family: inherit;
        }

        .form-group textarea {
            min-height: 100px;
            resize: vertical;
        }

        .form-group input:focus,
        .form-group select:focus,
        .form-group textarea:focus {
            outline: none;
            border-color: #3498db;
            box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
        }

        .form-row {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 1rem;
        }

        .section-hidden {
            display: none;
        }

        .record-link {
            color: #3498db;
            text-decoration: none;
            cursor: pointer;
        }

        .record-link:hover {
            text-decoration: underline;
        }

        .stats {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 1rem;
            margin-bottom: 2rem;
        }

        .stat-card {
            background: white;
            padding: 1.5rem;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }

        .stat-card h3 {
            font-size: 2rem;
            color: #3498db;
            margin-bottom: 0.5rem;
        }

        .stat-card p {
            color: #7f8c8d;
            font-size: 0.9rem;
        }

        .empty-state {
            text-align: center;
            padding: 3rem;
            color: #7f8c8d;
        }

        .empty-state-icon {
            font-size: 3rem;
            margin-bottom: 1rem;
        }

        .search-filter {
            margin-bottom: 1.5rem;
        }

        .search-filter input {
            width: 100%;
            padding: 0.75rem;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 0.95rem;
        }

        .action-buttons {
            display: flex;
            gap: 0.5rem;
        }

        .action-btn {
            padding: 0.25rem 0.75rem;
            font-size: 0.85rem;
            border-radius: 4px;
            border: none;
            cursor: pointer;
            transition: all 0.3s;
        }

        .action-btn-view {
            background: #3498db;
            color: white;
        }

        .action-btn-view:hover {
            background: #2980b9;
        }

        .action-btn-edit {
            background: #f39c12;
            color: white;
        }

        .action-btn-edit:hover {
            background: #e67e22;
        }

        .btn-danger {
            background: #e74c3c;
            color: white;
        }

        .btn-danger:hover {
            background: #c0392b;
        }

        .detail-view {
            display: grid;
            gap: 1rem;
        }

        .detail-row {
            display: grid;
            grid-template-columns: 200px 1fr;
            padding: 0.75rem 0;
            border-bottom: 1px solid #ecf0f1;
        }

        .detail-label {
            font-weight: 600;
            color: #2c3e50;
        }

        .detail-value {
            color: #555;
        }

        @media (max-width: 768px) {
            .form-row {
                grid-template-columns: 1fr;
            }

            .detail-row {
                grid-template-columns: 1fr;
                gap: 0.25rem;
            }

            .container {
                padding: 0 1rem;
            }

            .nav {
                overflow-x: auto;
            }
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>🔧 Local ITSM Tool</h1>
    </div>

    <div class="nav">
        <button class="active" onclick="switchSection('incidents')">Incidents</button>
        <button onclick="switchSection('ritm')">Request Items (RITM)</button>
        <button onclick="switchSection('changes')">Change Management</button>
        <button onclick="switchSection('dashboard')">Dashboard</button>
    </div>

    <div class="container">
        <!-- Dashboard Section -->
        <div id="dashboard-section" class="section-hidden">
            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
                <h2 style="margin: 0; color: #2c3e50;">Dashboard Overview</h2>
                <button class="btn btn-danger" onclick="clearAllData()">🗑️ Clear All Data</button>
            </div>
            <div class="stats">
                <div class="stat-card">
                    <h3 id="stat-incidents">0</h3>
                    <p>Total Incidents</p>
                </div>
                <div class="stat-card">
                    <h3 id="stat-ritm">0</h3>
                    <p>Request Items</p>
                </div>
                <div class="stat-card">
                    <h3 id="stat-changes">0</h3>
                    <p>Changes</p>
                </div>
                <div class="stat-card">
                    <h3 id="stat-open">0</h3>
                    <p>Open Items</p>
                </div>
            </div>
        </div>

        <!-- Incidents Section -->
        <div id="incidents-section">
            <div class="actions">
                <button class="btn btn-primary" onclick="openCreateModal('incident')">+ Create New Incident</button>
                <button class="btn btn-secondary" onclick="exportData('incidents')">Export to JSON</button>
                <button class="btn btn-danger" onclick="clearAllRecords('incidents')">Clear All Records</button>
            </div>

            <div class="search-filter">
                <input type="text" placeholder="Search incidents..." oninput="filterTable('incidents', this.value)">
            </div>

            <div class="card">
                <div class="card-header">Incident List</div>
                <div class="card-body">
                    <table id="incidents-table">
                        <thead>
                            <tr>
                                <th>Number</th>
                                <th>Short Description</th>
                                <th>Priority</th>
                                <th>Status</th>
                                <th>Assigned To</th>
                                <th>Created</th>
                                <th>Actions</th>
                            </tr>
                        </thead>
                        <tbody id="incidents-tbody">
                            <tr>
                                <td colspan="7" class="empty-state">
                                    <div class="empty-state-icon">📋</div>
                                    <p>No incidents found. Create your first incident to get started.</p>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>

        <!-- RITM Section -->
        <div id="ritm-section" class="section-hidden">
            <div class="actions">
                <button class="btn btn-primary" onclick="openCreateModal('ritm')">+ Create New Request Item</button>
                <button class="btn btn-secondary" onclick="exportData('ritm')">Export to JSON</button>
                <button class="btn btn-danger" onclick="clearAllRecords('ritm')">Clear All Records</button>
            </div>

            <div class="search-filter">
                <input type="text" placeholder="Search request items..." oninput="filterTable('ritm', this.value)">
            </div>

            <div class="card">
                <div class="card-header">Request Items (RITM) List</div>
                <div class="card-body">
                    <table id="ritm-table">
                        <thead>
                            <tr>
                                <th>Number</th>
                                <th>Short Description</th>
                                <th>Category</th>
                                <th>Status</th>
                                <th>Requested By</th>
                                <th>Created</th>
                                <th>Actions</th>
                            </tr>
                        </thead>
                        <tbody id="ritm-tbody">
                            <tr>
                                <td colspan="7" class="empty-state">
                                    <div class="empty-state-icon">📦</div>
                                    <p>No request items found. Create your first RITM to get started.</p>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>

        <!-- Changes Section -->
        <div id="changes-section" class="section-hidden">
            <div class="actions">
                <button class="btn btn-primary" onclick="openCreateModal('change')">+ Create New Change</button>
                <button class="btn btn-secondary" onclick="exportData('changes')">Export to JSON</button>
                <button class="btn btn-danger" onclick="clearAllRecords('changes')">Clear All Records</button>
            </div>

            <div class="search-filter">
                <input type="text" placeholder="Search changes..." oninput="filterTable('changes', this.value)">
            </div>

            <div class="card">
                <div class="card-header">Change Management List</div>
                <div class="card-body">
                    <table id="changes-table">
                        <thead>
                            <tr>
                                <th>Number</th>
                                <th>Short Description</th>
                                <th>Type</th>
                                <th>Risk</th>
                                <th>Status</th>
                                <th>Scheduled Date</th>
                                <th>Actions</th>
                            </tr>
                        </thead>
                        <tbody id="changes-tbody">
                            <tr>
                                <td colspan="7" class="empty-state">
                                    <div class="empty-state-icon">🔄</div>
                                    <p>No changes found. Create your first change request to get started.</p>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>

    <!-- Create/Edit Modal -->
    <div id="modal" class="modal">
        <div class="modal-content">
            <div class="modal-header">
                <h2 id="modal-title">Create New Incident</h2>
                <button class="close-btn" onclick="closeModal()">&times;</button>
            </div>
            <div class="modal-body" id="modal-body">
                <!-- Form will be dynamically inserted here -->
            </div>
            <div class="modal-footer">
                <button class="btn btn-secondary" onclick="closeModal()">Cancel</button>
                <button class="btn btn-success" id="save-btn" onclick="saveRecord()">Save</button>
            </div>
        </div>
    </div>

    <!-- View Modal -->
    <div id="view-modal" class="modal">
        <div class="modal-content">
            <div class="modal-header">
                <h2 id="view-modal-title">View Record</h2>
                <button class="close-btn" onclick="closeViewModal()">&times;</button>
            </div>
            <div class="modal-body" id="view-modal-body">
                <!-- Details will be dynamically inserted here -->
            </div>
            <div class="modal-footer">
                <button class="btn btn-secondary" onclick="closeViewModal()">Close</button>
                <button class="btn btn-primary" id="edit-from-view-btn" onclick="editFromView()">Edit</button>
            </div>
        </div>
    </div>

    <script>
        // Data Storage
        let incidents = JSON.parse(localStorage.getItem('itsm_incidents') || '[]');
        let ritms = JSON.parse(localStorage.getItem('itsm_ritms') || '[]');
        let changes = JSON.parse(localStorage.getItem('itsm_changes') || '[]');
        
        let currentSection = 'incidents';
        let currentRecordType = null;
        let currentRecordId = null;
        let viewingRecord = null;

        // Counter for IDs
        let incidentCounter = parseInt(localStorage.getItem('incident_counter') || '1000');
        let ritmCounter = parseInt(localStorage.getItem('ritm_counter') || '2000');
        let changeCounter = parseInt(localStorage.getItem('change_counter') || '3000');

        // Initialize the app
        function init() {
            renderIncidents();
            renderRITMs();
            renderChanges();
            updateDashboard();
        }

        // Switch between sections
        function switchSection(section) {
            // Hide all sections
            document.getElementById('dashboard-section').classList.add('section-hidden');
            document.getElementById('incidents-section').classList.add('section-hidden');
            document.getElementById('ritm-section').classList.add('section-hidden');
            document.getElementById('changes-section').classList.add('section-hidden');

            // Show selected section
            if (section === 'dashboard') {
                document.getElementById('dashboard-section').classList.remove('section-hidden');
                updateDashboard();
            } else if (section === 'incidents') {
                document.getElementById('incidents-section').classList.remove('section-hidden');
            } else if (section === 'ritm') {
                document.getElementById('ritm-section').classList.remove('section-hidden');
            } else if (section === 'changes') {
                document.getElementById('changes-section').classList.remove('section-hidden');
            }

            // Update nav active state
            document.querySelectorAll('.nav button').forEach(btn => {
                btn.classList.remove('active');
            });
            event.target.classList.add('active');
            
            currentSection = section;
        }

        // Update Dashboard
        function updateDashboard() {
            document.getElementById('stat-incidents').textContent = incidents.length;
            document.getElementById('stat-ritm').textContent = ritms.length;
            document.getElementById('stat-changes').textContent = changes.length;
            
            const openIncidents = incidents.filter(i => i.status !== 'Closed').length;
            const openRitms = ritms.filter(r => r.status !== 'Closed').length;
            const openChanges = changes.filter(c => c.status !== 'Implemented' && c.status !== 'Closed').length;
            
            document.getElementById('stat-open').textContent = openIncidents + openRitms + openChanges;
        }

        // Open Create/Edit Modal
        function openCreateModal(type, recordId = null) {
            currentRecordType = type;
            currentRecordId = recordId;
            
            const modal = document.getElementById('modal');
            const modalTitle = document.getElementById('modal-title');
            const modalBody = document.getElementById('modal-body');
            
            let title = '';
            let formHTML = '';
            
            if (type === 'incident') {
                title = recordId ? 'Edit Incident' : 'Create New Incident';
                formHTML = getIncidentForm(recordId);
            } else if (type === 'ritm') {
                title = recordId ? 'Edit Request Item' : 'Create New Request Item';
                formHTML = getRITMForm(recordId);
            } else if (type === 'change') {
                title = recordId ? 'Edit Change' : 'Create New Change';
                formHTML = getChangeForm(recordId);
            }
            
            modalTitle.textContent = title;
            modalBody.innerHTML = formHTML;
            modal.classList.add('active');
        }

        // Close Modal
        function closeModal() {
            document.getElementById('modal').classList.remove('active');
            currentRecordType = null;
            currentRecordId = null;
        }

        // Incident Form
        function getIncidentForm(id) {
            let record = id ? incidents.find(i => i.id === id) : {};
            
            return `
                <div class="form-row">
                    <div class="form-group">
                        <label>Short Description *</label>
                        <input type="text" id="short_description" value="${record.short_description || ''}" required>
                    </div>
                    <div class="form-group">
                        <label>Priority *</label>
                        <select id="priority">
                            <option value="Critical" ${record.priority === 'Critical' ? 'selected' : ''}>Critical</option>
                            <option value="High" ${record.priority === 'High' ? 'selected' : ''}>High</option>
                            <option value="Medium" ${record.priority === 'Medium' || !record.priority ? 'selected' : ''}>Medium</option>
                            <option value="Low" ${record.priority === 'Low' ? 'selected' : ''}>Low</option>
                        </select>
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label>Status *</label>
                        <select id="status">
                            <option value="New" ${record.status === 'New' || !record.status ? 'selected' : ''}>New</option>
                            <option value="In Progress" ${record.status === 'In Progress' ? 'selected' : ''}>In Progress</option>
                            <option value="Resolved" ${record.status === 'Resolved' ? 'selected' : ''}>Resolved</option>
                            <option value="Closed" ${record.status === 'Closed' ? 'selected' : ''}>Closed</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>Assigned To</label>
                        <input type="text" id="assigned_to" value="${record.assigned_to || ''}">
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label>Category</label>
                        <select id="category">
                            <option value="">-- Select --</option>
                            <option value="Hardware" ${record.category === 'Hardware' ? 'selected' : ''}>Hardware</option>
                            <option value="Software" ${record.category === 'Software' ? 'selected' : ''}>Software</option>
                            <option value="Network" ${record.category === 'Network' ? 'selected' : ''}>Network</option>
                            <option value="Database" ${record.category === 'Database' ? 'selected' : ''}>Database</option>
                            <option value="Security" ${record.category === 'Security' ? 'selected' : ''}>Security</option>
                            <option value="Other" ${record.category === 'Other' ? 'selected' : ''}>Other</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>Caller</label>
                        <input type="text" id="caller" value="${record.caller || ''}">
                    </div>
                </div>
                <div class="form-group">
                    <label>Description</label>
                    <textarea id="description">${record.description || ''}</textarea>
                </div>
                <div class="form-group">
                    <label>Resolution Notes</label>
                    <textarea id="resolution_notes">${record.resolution_notes || ''}</textarea>
                </div>
            `;
        }

        // RITM Form
        function getRITMForm(id) {
            let record = id ? ritms.find(r => r.id === id) : {};
            
            return `
                <div class="form-row">
                    <div class="form-group">
                        <label>Short Description *</label>
                        <input type="text" id="short_description" value="${record.short_description || ''}" required>
                    </div>
                    <div class="form-group">
                        <label>Category *</label>
                        <select id="category">
                            <option value="Hardware Request" ${record.category === 'Hardware Request' || !record.category ? 'selected' : ''}>Hardware Request</option>
                            <option value="Software Request" ${record.category === 'Software Request' ? 'selected' : ''}>Software Request</option>
                            <option value="Access Request" ${record.category === 'Access Request' ? 'selected' : ''}>Access Request</option>
                            <option value="Service Request" ${record.category === 'Service Request' ? 'selected' : ''}>Service Request</option>
                            <option value="Other" ${record.category === 'Other' ? 'selected' : ''}>Other</option>
                        </select>
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label>Status *</label>
                        <select id="status">
                            <option value="Pending Approval" ${record.status === 'Pending Approval' || !record.status ? 'selected' : ''}>Pending Approval</option>
                            <option value="Approved" ${record.status === 'Approved' ? 'selected' : ''}>Approved</option>
                            <option value="Rejected" ${record.status === 'Rejected' ? 'selected' : ''}>Rejected</option>
                            <option value="In Progress" ${record.status === 'In Progress' ? 'selected' : ''}>In Progress</option>
                            <option value="Completed" ${record.status === 'Completed' ? 'selected' : ''}>Completed</option>
                            <option value="Closed" ${record.status === 'Closed' ? 'selected' : ''}>Closed</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>Requested By</label>
                        <input type="text" id="requested_by" value="${record.requested_by || ''}">
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label>Assigned To</label>
                        <input type="text" id="assigned_to" value="${record.assigned_to || ''}">
                    </div>
                    <div class="form-group">
                        <label>Due Date</label>
                        <input type="date" id="due_date" value="${record.due_date || ''}">
                    </div>
                </div>
                <div class="form-group">
                    <label>Description</label>
                    <textarea id="description">${record.description || ''}</textarea>
                </div>
                <div class="form-group">
                    <label>Fulfillment Notes</label>
                    <textarea id="fulfillment_notes">${record.fulfillment_notes || ''}</textarea>
                </div>
            `;
        }

        // Change Form
        function getChangeForm(id) {
            let record = id ? changes.find(c => c.id === id) : {};
            
            return `
                <div class="form-row">
                    <div class="form-group">
                        <label>Short Description *</label>
                        <input type="text" id="short_description" value="${record.short_description || ''}" required>
                    </div>
                    <div class="form-group">
                        <label>Type *</label>
                        <select id="type">
                            <option value="Standard" ${record.type === 'Standard' || !record.type ? 'selected' : ''}>Standard</option>
                            <option value="Normal" ${record.type === 'Normal' ? 'selected' : ''}>Normal</option>
                            <option value="Emergency" ${record.type === 'Emergency' ? 'selected' : ''}>Emergency</option>
                        </select>
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label>Risk *</label>
                        <select id="risk">
                            <option value="Low" ${record.risk === 'Low' || !record.risk ? 'selected' : ''}>Low</option>
                            <option value="Medium" ${record.risk === 'Medium' ? 'selected' : ''}>Medium</option>
                            <option value="High" ${record.risk === 'High' ? 'selected' : ''}>High</option>
                            <option value="Critical" ${record.risk === 'Critical' ? 'selected' : ''}>Critical</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label>Status *</label>
                        <select id="status">
                            <option value="Draft" ${record.status === 'Draft' || !record.status ? 'selected' : ''}>Draft</option>
                            <option value="Pending Approval" ${record.status === 'Pending Approval' ? 'selected' : ''}>Pending Approval</option>
                            <option value="Approved" ${record.status === 'Approved' ? 'selected' : ''}>Approved</option>
                            <option value="Scheduled" ${record.status === 'Scheduled' ? 'selected' : ''}>Scheduled</option>
                            <option value="In Progress" ${record.status === 'In Progress' ? 'selected' : ''}>In Progress</option>
                            <option value="Implemented" ${record.status === 'Implemented' ? 'selected' : ''}>Implemented</option>
                            <option value="Closed" ${record.status === 'Closed' ? 'selected' : ''}>Closed</option>
                        </select>
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label>Requested By</label>
                        <input type="text" id="requested_by" value="${record.requested_by || ''}">
                    </div>
                    <div class="form-group">
                        <label>Assigned To</label>
                        <input type="text" id="assigned_to" value="${record.assigned_to || ''}">
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label>Scheduled Start Date</label>
                        <input type="datetime-local" id="scheduled_start" value="${record.scheduled_start || ''}">
                    </div>
                    <div class="form-group">
                        <label>Scheduled End Date</label>
                        <input type="datetime-local" id="scheduled_end" value="${record.scheduled_end || ''}">
                    </div>
                </div>
                <div class="form-group">
                    <label>Description</label>
                    <textarea id="description">${record.description || ''}</textarea>
                </div>
                <div class="form-group">
                    <label>Implementation Plan</label>
                    <textarea id="implementation_plan">${record.implementation_plan || ''}</textarea>
                </div>
                <div class="form-group">
                    <label>Backout Plan</label>
                    <textarea id="backout_plan">${record.backout_plan || ''}</textarea>
                </div>
                <div class="form-group">
                    <label>Test Plan</label>
                    <textarea id="test_plan">${record.test_plan || ''}</textarea>
                </div>
            `;
        }

        // Save Record
        function saveRecord() {
            const short_description = document.getElementById('short_description').value.trim();
            
            if (!short_description) {
                alert('Please fill in the required fields');
                return;
            }
            
            if (currentRecordType === 'incident') {
                saveIncident();
            } else if (currentRecordType === 'ritm') {
                saveRITM();
            } else if (currentRecordType === 'change') {
                saveChange();
            }
            
            closeModal();
        }

        // Save Incident
        function saveIncident() {
            const record = {
                id: currentRecordId || `INC${incidentCounter++}`,
                number: currentRecordId || `INC${incidentCounter - 1}`,
                short_description: document.getElementById('short_description').value,
                priority: document.getElementById('priority').value,
                status: document.getElementById('status').value,
                assigned_to: document.getElementById('assigned_to').value,
                category: document.getElementById('category').value,
                caller: document.getElementById('caller').value,
                description: document.getElementById('description').value,
                resolution_notes: document.getElementById('resolution_notes').value,
                created: currentRecordId ? incidents.find(i => i.id === currentRecordId).created : new Date().toISOString(),
                updated: new Date().toISOString()
            };
            
            if (currentRecordId) {
                const index = incidents.findIndex(i => i.id === currentRecordId);
                incidents[index] = record;
            } else {
                incidents.push(record);
                localStorage.setItem('incident_counter', incidentCounter);
            }
            
            localStorage.setItem('itsm_incidents', JSON.stringify(incidents));
            renderIncidents();
            updateDashboard();
        }

        // Save RITM
        function saveRITM() {
            const record = {
                id: currentRecordId || `RITM${ritmCounter++}`,
                number: currentRecordId || `RITM${ritmCounter - 1}`,
                short_description: document.getElementById('short_description').value,
                category: document.getElementById('category').value,
                status: document.getElementById('status').value,
                requested_by: document.getElementById('requested_by').value,
                assigned_to: document.getElementById('assigned_to').value,
                due_date: document.getElementById('due_date').value,
                description: document.getElementById('description').value,
                fulfillment_notes: document.getElementById('fulfillment_notes').value,
                created: currentRecordId ? ritms.find(r => r.id === currentRecordId).created : new Date().toISOString(),
                updated: new Date().toISOString()
            };
            
            if (currentRecordId) {
                const index = ritms.findIndex(r => r.id === currentRecordId);
                ritms[index] = record;
            } else {
                ritms.push(record);
                localStorage.setItem('ritm_counter', ritmCounter);
            }
            
            localStorage.setItem('itsm_ritms', JSON.stringify(ritms));
            renderRITMs();
            updateDashboard();
        }

        // Save Change
        function saveChange() {
            const record = {
                id: currentRecordId || `CHG${changeCounter++}`,
                number: currentRecordId || `CHG${changeCounter - 1}`,
                short_description: document.getElementById('short_description').value,
                type: document.getElementById('type').value,
                risk: document.getElementById('risk').value,
                status: document.getElementById('status').value,
                requested_by: document.getElementById('requested_by').value,
                assigned_to: document.getElementById('assigned_to').value,
                scheduled_start: document.getElementById('scheduled_start').value,
                scheduled_end: document.getElementById('scheduled_end').value,
                description: document.getElementById('description').value,
                implementation_plan: document.getElementById('implementation_plan').value,
                backout_plan: document.getElementById('backout_plan').value,
                test_plan: document.getElementById('test_plan').value,
                created: currentRecordId ? changes.find(c => c.id === currentRecordId).created : new Date().toISOString(),
                updated: new Date().toISOString()
            };
            
            if (currentRecordId) {
                const index = changes.findIndex(c => c.id === currentRecordId);
                changes[index] = record;
            } else {
                changes.push(record);
                localStorage.setItem('change_counter', changeCounter);
            }
            
            localStorage.setItem('itsm_changes', JSON.stringify(changes));
            renderChanges();
            updateDashboard();
        }

        // Render Incidents
        function renderIncidents() {
            const tbody = document.getElementById('incidents-tbody');
            
            if (incidents.length === 0) {
                tbody.innerHTML = `
                    <tr>
                        <td colspan="7" class="empty-state">
                            <div class="empty-state-icon">📋</div>
                            <p>No incidents found. Create your first incident to get started.</p>
                        </td>
                    </tr>
                `;
                return;
            }
            
            tbody.innerHTML = incidents.map(inc => `
                <tr>
                    <td><a class="record-link" onclick="viewRecord('incident', '${inc.id}')">${inc.number}</a></td>
                    <td>${inc.short_description}</td>
                    <td><span class="priority-${inc.priority.toLowerCase()}">${inc.priority}</span></td>
                    <td><span class="badge badge-${inc.status.toLowerCase().replace(' ', '')}">${inc.status}</span></td>
                    <td>${inc.assigned_to || '-'}</td>
                    <td>${formatDate(inc.created)}</td>
                    <td>
                        <div class="action-buttons">
                            <button class="action-btn action-btn-view" onclick="viewRecord('incident', '${inc.id}')">View</button>
                            <button class="action-btn action-btn-edit" onclick="openCreateModal('incident', '${inc.id}')">Edit</button>
                        </div>
                    </td>
                </tr>
            `).join('');
        }

        // Render RITMs
        function renderRITMs() {
            const tbody = document.getElementById('ritm-tbody');
            
            if (ritms.length === 0) {
                tbody.innerHTML = `
                    <tr>
                        <td colspan="7" class="empty-state">
                            <div class="empty-state-icon">📦</div>
                            <p>No request items found. Create your first RITM to get started.</p>
                        </td>
                    </tr>
                `;
                return;
            }
            
            tbody.innerHTML = ritms.map(ritm => `
                <tr>
                    <td><a class="record-link" onclick="viewRecord('ritm', '${ritm.id}')">${ritm.number}</a></td>
                    <td>${ritm.short_description}</td>
                    <td>${ritm.category}</td>
                    <td><span class="badge badge-${ritm.status.toLowerCase().replace(' ', '')}">${ritm.status}</span></td>
                    <td>${ritm.requested_by || '-'}</td>
                    <td>${formatDate(ritm.created)}</td>
                    <td>
                        <div class="action-buttons">
                            <button class="action-btn action-btn-view" onclick="viewRecord('ritm', '${ritm.id}')">View</button>
                            <button class="action-btn action-btn-edit" onclick="openCreateModal('ritm', '${ritm.id}')">Edit</button>
                        </div>
                    </td>
                </tr>
            `).join('');
        }

        // Render Changes
        function renderChanges() {
            const tbody = document.getElementById('changes-tbody');
            
            if (changes.length === 0) {
                tbody.innerHTML = `
                    <tr>
                        <td colspan="7" class="empty-state">
                            <div class="empty-state-icon">🔄</div>
                            <p>No changes found. Create your first change request to get started.</p>
                        </td>
                    </tr>
                `;
                return;
            }
            
            tbody.innerHTML = changes.map(chg => `
                <tr>
                    <td><a class="record-link" onclick="viewRecord('change', '${chg.id}')">${chg.number}</a></td>
                    <td>${chg.short_description}</td>
                    <td>${chg.type}</td>
                    <td><span class="priority-${chg.risk.toLowerCase()}">${chg.risk}</span></td>
                    <td><span class="badge badge-${chg.status.toLowerCase().replace(' ', '')}">${chg.status}</span></td>
                    <td>${chg.scheduled_start ? formatDate(chg.scheduled_start) : '-'}</td>
                    <td>
                        <div class="action-buttons">
                            <button class="action-btn action-btn-view" onclick="viewRecord('change', '${chg.id}')">View</button>
                            <button class="action-btn action-btn-edit" onclick="openCreateModal('change', '${chg.id}')">Edit</button>
                        </div>
                    </td>
                </tr>
            `).join('');
        }

        // View Record
        function viewRecord(type, id) {
            viewingRecord = { type, id };
            const modal = document.getElementById('view-modal');
            const modalTitle = document.getElementById('view-modal-title');
            const modalBody = document.getElementById('view-modal-body');
            
            let record, detailsHTML;
            
            if (type === 'incident') {
                record = incidents.find(i => i.id === id);
                modalTitle.textContent = `Incident: ${record.number}`;
                detailsHTML = `
                    <div class="detail-view">
                        <div class="detail-row">
                            <div class="detail-label">Number</div>
                            <div class="detail-value">${record.number}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Short Description</div>
                            <div class="detail-value">${record.short_description}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Priority</div>
                            <div class="detail-value"><span class="priority-${record.priority.toLowerCase()}">${record.priority}</span></div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Status</div>
                            <div class="detail-value"><span class="badge badge-${record.status.toLowerCase().replace(' ', '')}">${record.status}</span></div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Category</div>
                            <div class="detail-value">${record.category || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Assigned To</div>
                            <div class="detail-value">${record.assigned_to || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Caller</div>
                            <div class="detail-value">${record.caller || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Description</div>
                            <div class="detail-value">${record.description || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Resolution Notes</div>
                            <div class="detail-value">${record.resolution_notes || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Created</div>
                            <div class="detail-value">${formatDate(record.created)}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Last Updated</div>
                            <div class="detail-value">${formatDate(record.updated)}</div>
                        </div>
                    </div>
                `;
            } else if (type === 'ritm') {
                record = ritms.find(r => r.id === id);
                modalTitle.textContent = `Request Item: ${record.number}`;
                detailsHTML = `
                    <div class="detail-view">
                        <div class="detail-row">
                            <div class="detail-label">Number</div>
                            <div class="detail-value">${record.number}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Short Description</div>
                            <div class="detail-value">${record.short_description}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Category</div>
                            <div class="detail-value">${record.category}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Status</div>
                            <div class="detail-value"><span class="badge badge-${record.status.toLowerCase().replace(' ', '')}">${record.status}</span></div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Requested By</div>
                            <div class="detail-value">${record.requested_by || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Assigned To</div>
                            <div class="detail-value">${record.assigned_to || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Due Date</div>
                            <div class="detail-value">${record.due_date ? formatDate(record.due_date) : '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Description</div>
                            <div class="detail-value">${record.description || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Fulfillment Notes</div>
                            <div class="detail-value">${record.fulfillment_notes || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Created</div>
                            <div class="detail-value">${formatDate(record.created)}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Last Updated</div>
                            <div class="detail-value">${formatDate(record.updated)}</div>
                        </div>
                    </div>
                `;
            } else if (type === 'change') {
                record = changes.find(c => c.id === id);
                modalTitle.textContent = `Change: ${record.number}`;
                detailsHTML = `
                    <div class="detail-view">
                        <div class="detail-row">
                            <div class="detail-label">Number</div>
                            <div class="detail-value">${record.number}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Short Description</div>
                            <div class="detail-value">${record.short_description}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Type</div>
                            <div class="detail-value">${record.type}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Risk</div>
                            <div class="detail-value"><span class="priority-${record.risk.toLowerCase()}">${record.risk}</span></div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Status</div>
                            <div class="detail-value"><span class="badge badge-${record.status.toLowerCase().replace(' ', '')}">${record.status}</span></div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Requested By</div>
                            <div class="detail-value">${record.requested_by || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Assigned To</div>
                            <div class="detail-value">${record.assigned_to || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Scheduled Start</div>
                            <div class="detail-value">${record.scheduled_start ? formatDate(record.scheduled_start) : '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Scheduled End</div>
                            <div class="detail-value">${record.scheduled_end ? formatDate(record.scheduled_end) : '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Description</div>
                            <div class="detail-value">${record.description || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Implementation Plan</div>
                            <div class="detail-value">${record.implementation_plan || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Backout Plan</div>
                            <div class="detail-value">${record.backout_plan || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Test Plan</div>
                            <div class="detail-value">${record.test_plan || '-'}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Created</div>
                            <div class="detail-value">${formatDate(record.created)}</div>
                        </div>
                        <div class="detail-row">
                            <div class="detail-label">Last Updated</div>
                            <div class="detail-value">${formatDate(record.updated)}</div>
                        </div>
                    </div>
                `;
            }
            
            modalBody.innerHTML = detailsHTML;
            modal.classList.add('active');
        }

        // Close View Modal
        function closeViewModal() {
            document.getElementById('view-modal').classList.remove('active');
            viewingRecord = null;
        }

        // Edit from View
        function editFromView() {
            if (viewingRecord) {
                closeViewModal();
                openCreateModal(viewingRecord.type, viewingRecord.id);
            }
        }

        // Filter Table
        function filterTable(type, searchTerm) {
            const term = searchTerm.toLowerCase();
            let data;
            
            if (type === 'incidents') {
                data = incidents;
            } else if (type === 'ritm') {
                data = ritms;
            } else if (type === 'changes') {
                data = changes;
            }
            
            const filtered = data.filter(record => {
                return record.short_description.toLowerCase().includes(term) ||
                       record.number.toLowerCase().includes(term) ||
                       (record.status && record.status.toLowerCase().includes(term));
            });
            
            // Re-render with filtered data
            const originalData = type === 'incidents' ? incidents : type === 'ritm' ? ritms : changes;
            if (type === 'incidents') {
                incidents = filtered;
                renderIncidents();
                incidents = originalData;
            } else if (type === 'ritm') {
                ritms = filtered;
                renderRITMs();
                ritms = originalData;
            } else if (type === 'changes') {
                changes = filtered;
                renderChanges();
                changes = originalData;
            }
        }

        // Export Data
        function exportData(type) {
            let data, filename;
            
            if (type === 'incidents') {
                data = incidents;
                filename = 'incidents.json';
            } else if (type === 'ritm') {
                data = ritms;
                filename = 'ritms.json';
            } else if (type === 'changes') {
                data = changes;
                filename = 'changes.json';
            }
            
            const dataStr = JSON.stringify(data, null, 2);
            const dataBlob = new Blob([dataStr], { type: 'application/json' });
            const url = URL.createObjectURL(dataBlob);
            const link = document.createElement('a');
            link.href = url;
            link.download = filename;
            link.click();
        }

        // Clear All Records
        function clearAllRecords(type) {
            let typeName, count;
            
            if (type === 'incidents') {
                typeName = 'Incidents';
                count = incidents.length;
            } else if (type === 'ritm') {
                typeName = 'Request Items';
                count = ritms.length;
            } else if (type === 'changes') {
                typeName = 'Changes';
                count = changes.length;
            }
            
            if (count === 0) {
                alert('There are no records to delete.');
                return;
            }
            
            const confirmed = confirm(
                `⚠️ WARNING: This will permanently delete all ${count} ${typeName}.\n\n` +
                `This action cannot be undone!\n\n` +
                `Click OK to proceed with deletion, or Cancel to keep your records.`
            );
            
            if (confirmed) {
                // Double confirmation for safety
                const doubleConfirm = confirm(
                    `Are you absolutely sure?\n\n` +
                    `This is your last chance to cancel before deleting ${count} ${typeName}.`
                );
                
                if (doubleConfirm) {
                    if (type === 'incidents') {
                        incidents = [];
                        localStorage.setItem('itsm_incidents', JSON.stringify(incidents));
                        renderIncidents();
                    } else if (type === 'ritm') {
                        ritms = [];
                        localStorage.setItem('itsm_ritms', JSON.stringify(ritms));
                        renderRITMs();
                    } else if (type === 'changes') {
                        changes = [];
                        localStorage.setItem('itsm_changes', JSON.stringify(changes));
                        renderChanges();
                    }
                    
                    updateDashboard();
                    alert(`✓ Successfully deleted all ${typeName}.`);
                }
            }
        }

        // Clear All Data (Everything)
        function clearAllData() {
            const totalRecords = incidents.length + ritms.length + changes.length;
            
            if (totalRecords === 0) {
                alert('There are no records to delete.');
                return;
            }
            
            const confirmed = confirm(
                `⚠️ DANGER: This will permanently delete ALL data:\n\n` +
                `• ${incidents.length} Incidents\n` +
                `• ${ritms.length} Request Items\n` +
                `• ${changes.length} Changes\n\n` +
                `Total: ${totalRecords} records\n\n` +
                `This action CANNOT be undone!\n\n` +
                `Click OK to proceed with deletion, or Cancel to keep your data.`
            );
            
            if (confirmed) {
                // Triple confirmation for clearing everything
                const doubleConfirm = confirm(
                    `🚨 FINAL WARNING 🚨\n\n` +
                    `You are about to DELETE EVERYTHING (${totalRecords} records).\n\n` +
                    `This is your LAST CHANCE to cancel!\n\n` +
                    `Type anything in the prompt that appears next to confirm.`
                );
                
                if (doubleConfirm) {
                    const finalConfirm = prompt(
                        `To confirm deletion of ALL ${totalRecords} records, type: DELETE`
                    );
                    
                    if (finalConfirm === 'DELETE') {
                        // Clear all data
                        incidents = [];
                        ritms = [];
                        changes = [];
                        
                        // Clear localStorage
                        localStorage.setItem('itsm_incidents', JSON.stringify(incidents));
                        localStorage.setItem('itsm_ritms', JSON.stringify(ritms));
                        localStorage.setItem('itsm_changes', JSON.stringify(changes));
                        
                        // Re-render all sections
                        renderIncidents();
                        renderRITMs();
                        renderChanges();
                        updateDashboard();
                        
                        alert('✓ All data has been permanently deleted.');
                    } else {
                        alert('Deletion cancelled. You did not type DELETE correctly.');
                    }
                }
            }
        }

        // Format Date
        function formatDate(dateString) {
            const date = new Date(dateString);
            return date.toLocaleString('en-US', {
                year: 'numeric',
                month: 'short',
                day: 'numeric',
                hour: '2-digit',
                minute: '2-digit'
            });
        }

        // Initialize on load
        window.onload = init;
    </script>
</body>
</html>

Clone this wiki locally