master-brain-api / files /support.js
Dilip8756's picture
Upload 100 files
58c1398 verified
/**
* Support Page Logic - Aadhaar Pro
* Updated: real API calls, category field, ticket status colours
*/
document.addEventListener('DOMContentLoaded', () => {
initSupportPage();
});
function initSupportPage() {
loadRecentTickets();
setupTicketForm();
}
// ── Form submission ────────────────────────────────────────────────
function setupTicketForm() {
const form = document.getElementById('ticket-form');
if (!form) return;
form.addEventListener('submit', async (e) => {
e.preventDefault();
const data = {
subject: document.getElementById('tick-subject').value.trim(),
message: document.getElementById('tick-message').value.trim(),
category: document.getElementById('tick-category')?.value || 'other'
};
if (!data.subject || !data.message) {
alert('Subject aur message dono bharna zaroori hai.');
return;
}
const btn = form.querySelector('[type="submit"]');
btn.disabled = true;
try {
const res = await fetch('/api/support/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const body = await res.json();
if (body.success) {
alert(`Ticket submit ho gaya! Ticket No: ${body.ticket_number}\nHamari team jald reply karegi.`);
form.reset();
loadRecentTickets();
} else {
alert('Error: ' + (body.error || 'Unknown error'));
}
} catch (err) {
console.error('Support ticket error:', err);
alert('Network error. Please try again.');
} finally {
btn.disabled = false;
}
});
}
// ── Load ticket list ───────────────────────────────────────────────
async function loadRecentTickets() {
const container = document.getElementById('tickets-container');
if (!container) return;
container.innerHTML = '<p style="color:var(--text-muted);font-size:0.85rem;">Loading...</p>';
try {
const res = await fetch('/api/support/list');
const tickets = await res.json();
if (!Array.isArray(tickets) || tickets.length === 0) {
container.innerHTML = '<p style="color:var(--text-muted);font-size:0.85rem;">Koi active ticket nahi mila.</p>';
return;
}
container.innerHTML = tickets.map(t => `
<div class="ticket-status-item" onclick="openTicketDetail('${t.id}')" style="cursor:pointer;">
<div class="ticket-info">
<span class="id">#${t.ticket_number}</span>
<div class="subject">${t.subject}</div>
<small style="color:var(--text-muted);font-size:0.75rem;">${t.date}</small>
</div>
<span class="status-tag status-${t.status}">
${statusLabel(t.status)}
</span>
</div>
`).join('');
} catch (err) {
console.error('Error loading tickets:', err);
container.innerHTML = '<p class="error-text">Ticket history load nahi hua.</p>';
}
}
// ── Ticket detail modal ────────────────────────────────────────────
async function openTicketDetail(ticketId) {
try {
const res = await fetch(`/api/support/ticket/${ticketId}`);
const ticket = await res.json();
if (ticket.error) { alert(ticket.error); return; }
// Build modal HTML
const messagesHtml = ticket.messages.map(m => `
<div style="display:flex;flex-direction:column;align-items:${m.sender === 'user' ? 'flex-start' : 'flex-end'};margin-bottom:12px;">
<div style="
max-width:80%;
padding:10px 14px;
border-radius:${m.sender === 'user' ? '4px 12px 12px 12px' : '12px 4px 12px 12px'};
background:${m.sender === 'user' ? 'var(--card-bg, #f5f5f5)' : 'var(--primary-color, #4361ee)'};
color:${m.sender === 'user' ? 'var(--text-color)' : '#fff'};
font-size:0.9rem;line-height:1.5;
border:${m.sender === 'user' ? '1px solid var(--border-color)' : 'none'};
">${m.message}</div>
<small style="color:var(--text-muted);font-size:0.72rem;margin-top:4px;">
${m.sender === 'admin' ? 'Support Team' : 'Aap'} Β· ${m.time}
</small>
</div>
`).join('');
showTicketModal({
number: ticket.ticket_number,
subject: ticket.subject,
status: ticket.status,
category: ticket.category,
date: ticket.date,
messages: messagesHtml
});
} catch (err) {
console.error('openTicketDetail error:', err);
alert('Ticket detail load nahi hua.');
}
}
function showTicketModal({ number, subject, status, category, date, messages }) {
// Remove existing modal if any
document.getElementById('ticket-detail-modal')?.remove();
const modal = document.createElement('div');
modal.id = 'ticket-detail-modal';
modal.style.cssText = `
position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999;
background:rgba(0,0,0,0.55);backdrop-filter:blur(6px);
display:flex;justify-content:center;align-items:center;
`;
modal.innerHTML = `
<div style="
width:100%;max-width:480px;max-height:85vh;overflow-y:auto;
background:var(--card-bg, #fff);border-radius:16px;padding:28px 24px;
position:relative;font-family:'Outfit',sans-serif;
">
<button onclick="document.getElementById('ticket-detail-modal').remove()"
style="position:absolute;top:16px;right:18px;background:none;border:none;
font-size:1.3rem;cursor:pointer;color:var(--text-muted);">βœ•</button>
<div style="margin-bottom:18px;">
<span style="font-size:0.78rem;color:var(--text-muted);">#${number}</span>
<h3 style="margin:4px 0 8px;font-size:1.1rem;">${subject}</h3>
<div style="display:flex;gap:8px;flex-wrap:wrap;">
<span class="status-tag status-${status}">${statusLabel(status)}</span>
<span style="font-size:0.78rem;color:var(--text-muted);padding-top:2px;">${categoryLabel(category)} Β· ${date}</span>
</div>
</div>
<div style="border-top:1px solid var(--border-color);padding-top:16px;">
${messages}
</div>
</div>
`;
// Close on backdrop click
modal.addEventListener('click', (e) => {
if (e.target === modal) modal.remove();
});
document.body.appendChild(modal);
}
// ── Helpers ────────────────────────────────────────────────────────
function statusLabel(status) {
const map = { open: 'OPEN', pending: 'PENDING', resolved: 'RESOLVED', closed: 'CLOSED' };
return map[status] || status.toUpperCase();
}
function categoryLabel(cat) {
const map = { payment: 'Payment', wallet: 'Wallet', refund: 'Refund', other: 'Other' };
return map[cat] || cat;
}