[deploy] fix ticket dashboard tabs/icons
All checks were successful
Deploy Discord Bot / deploy (push) Successful in 37s
All checks were successful
Deploy Discord Bot / deploy (push) Successful in 37s
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Router } from 'express';
|
||||
import { Router } from 'express';
|
||||
|
||||
const router = Router();
|
||||
|
||||
@@ -43,18 +43,18 @@ router.get('/', (req, res) => {
|
||||
<aside class="sidebar">
|
||||
<div class="brand">Papo Control</div>
|
||||
<div class="nav">
|
||||
<a class="active" href="#overview" data-target="overview"><span class="icon">ðŸ </span> Uebersicht</a>
|
||||
<a href="#tickets" data-target="tickets"><span class="icon">🎫</span> Ticketsystem</a>
|
||||
<a href="#automod" data-target="automod" class="automod-link"><span class="icon">🛡ï¸</span> Automod</a>
|
||||
<a href="#welcome" data-target="welcome" class="welcome-link"><span class="icon">✨</span> Willkommen</a>
|
||||
<a href="#dynamicvoice" data-target="dynamicvoice" class="dynamicvoice-link"><span class="icon">🎧</span> Dynamic Voice</a>
|
||||
<a href="#birthday" data-target="birthday" class="birthday-link"><span class="icon">🎂</span> Birthday</a>
|
||||
<a href="#reactionroles" data-target="reactionroles" class="reactionroles-link"><span class="icon">😎</span> Reaction Roles</a>
|
||||
<a href="#statuspage" data-target="statuspage" class="statuspage-link"><span class="icon">🖥ï¸</span> Statuspage</a>
|
||||
<a href="#settings" data-target="settings"><span class="icon">âš™ï¸</span> Einstellungen</a>
|
||||
<a href="#modules" data-target="modules"><span class="icon">🧩</span> Module</a>
|
||||
<a href="#events" data-target="events" class="events-link"><span class="icon">📅</span> Events</a>
|
||||
<a href="#admin" data-target="admin" class="admin-link hidden"><span class="icon">🛡</span> Admin</a>
|
||||
<a class="active" href="#overview" data-target="overview"><span class="icon">🏠</span> Uebersicht</a>
|
||||
<a href="#tickets" data-target="tickets"><span class="icon">🎫</span> Ticketsystem</a>
|
||||
<a href="#automod" data-target="automod" class="automod-link"><span class="icon">🛡️</span> Automod</a>
|
||||
<a href="#welcome" data-target="welcome" class="welcome-link"><span class="icon">✨</span> Willkommen</a>
|
||||
<a href="#dynamicvoice" data-target="dynamicvoice" class="dynamicvoice-link"><span class="icon">🎧</span> Dynamic Voice</a>
|
||||
<a href="#birthday" data-target="birthday" class="birthday-link"><span class="icon">🎂</span> Birthday</a>
|
||||
<a href="#reactionroles" data-target="reactionroles" class="reactionroles-link"><span class="icon">😎</span> Reaction Roles</a>
|
||||
<a href="#statuspage" data-target="statuspage" class="statuspage-link"><span class="icon">🖥️</span> Statuspage</a>
|
||||
<a href="#settings" data-target="settings"><span class="icon">⚙️</span> Einstellungen</a>
|
||||
<a href="#modules" data-target="modules"><span class="icon">🧩</span> Module</a>
|
||||
<a href="#events" data-target="events" class="events-link"><span class="icon">📅</span> Events</a>
|
||||
<a href="#admin" data-target="admin" class="admin-link hidden"><span class="icon">🛡</span> Admin</a>
|
||||
</div>
|
||||
<div class="muted">Angemeldet als <span id="userInfo"></span></div>
|
||||
<button id="logoutBtn" class="logout">Logout</button>
|
||||
@@ -330,10 +330,10 @@ router.get('/', (req, res) => {
|
||||
<div class="card" style="display:flex; gap:10px; flex-wrap:wrap; align-items:center; justify-content:space-between;">
|
||||
<div>
|
||||
<p class="section-title">Tickets</p>
|
||||
<p class="section-sub">Übersicht, Pipeline, SLA, Automationen, Knowledge-Base.</p>
|
||||
<p class="section-sub"><EFBFBD>bersicht, Pipeline, SLA, Automationen, Knowledge-Base.</p>
|
||||
</div>
|
||||
<div class="row" style="gap:8px; flex-wrap:wrap;">
|
||||
<button class="secondary-btn ticket-tab-btn active" data-tab="overview">Übersicht</button>
|
||||
<button class="secondary-btn ticket-tab-btn active" data-tab="overview"><EFBFBD>bersicht</button>
|
||||
<button class="secondary-btn ticket-tab-btn" data-tab="pipeline">Pipeline</button>
|
||||
<button class="secondary-btn ticket-tab-btn" data-tab="sla">SLA</button>
|
||||
<button class="secondary-btn ticket-tab-btn" data-tab="automations">Automationen</button>
|
||||
@@ -346,7 +346,7 @@ router.get('/', (req, res) => {
|
||||
<div style="display:flex; align-items:center; justify-content:space-between; gap:12px;">
|
||||
<div>
|
||||
<p class="section-title">Ticketliste</p>
|
||||
<p class="section-sub">Links auswählen, Details im Modal. Plus öffnet Panel-Erstellung.</p>
|
||||
<p class="section-sub">Links ausw<EFBFBD>hlen, Details im Modal. Plus <EFBFBD>ffnet Panel-Erstellung.</p>
|
||||
</div>
|
||||
<div class="row" style="gap:10px;">
|
||||
<button class="secondary-btn" id="openSupportLogin" type="button">Support-Login Einstellungen</button>
|
||||
@@ -361,7 +361,7 @@ router.get('/', (req, res) => {
|
||||
<p class="section-title">Support-Login Status</p>
|
||||
<p class="section-sub">Aktive Supporter und letzte Sessions.</p>
|
||||
</div>
|
||||
<button class="icon-button" id="refreshSupportStatus">⟳</button>
|
||||
<button class="icon-button" id="refreshSupportStatus">?</button>
|
||||
</div>
|
||||
<div class="grid" style="grid-template-columns: repeat(auto-fit, minmax(240px,1fr)); gap:12px;">
|
||||
<div>
|
||||
@@ -381,7 +381,7 @@ router.get('/', (req, res) => {
|
||||
<div style="display:flex; justify-content:space-between; align-items:center; gap:12px;">
|
||||
<div>
|
||||
<p class="section-title">Status-Pipeline</p>
|
||||
<p class="section-sub">Tickets nach Phase. Status per Dropdown ändern.</p>
|
||||
<p class="section-sub">Tickets nach Phase. Status per Dropdown <EFBFBD>ndern.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid" style="grid-template-columns: repeat(auto-fit, minmax(240px,1fr)); gap:12px;" id="pipelineGrid">
|
||||
@@ -430,7 +430,7 @@ router.get('/', (req, res) => {
|
||||
<div style="display:flex; justify-content:space-between; gap:12px; flex-wrap:wrap;">
|
||||
<div>
|
||||
<p class="section-title">Automationen</p>
|
||||
<p class="section-sub">Regeln für Ticket-Aktionen.</p>
|
||||
<p class="section-sub">Regeln f<EFBFBD>r Ticket-Aktionen.</p>
|
||||
</div>
|
||||
<button class="secondary-btn" id="addAutomation">Neue Regel</button>
|
||||
</div>
|
||||
@@ -467,7 +467,7 @@ router.get('/', (req, res) => {
|
||||
<div style="display:flex; justify-content:space-between; gap:12px; flex-wrap:wrap;">
|
||||
<div>
|
||||
<p class="section-title">Knowledge-Base</p>
|
||||
<p class="section-sub">Artikel für Self-Service.</p>
|
||||
<p class="section-sub">Artikel f<EFBFBD>r Self-Service.</p>
|
||||
</div>
|
||||
<button class="secondary-btn" id="addKb">Neuer Artikel</button>
|
||||
</div>
|
||||
@@ -586,7 +586,7 @@ router.get('/', (req, res) => {
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label class="form-label">Embed Footer</label>
|
||||
<input id="welcomeFooter" placeholder="Schön, dass du da bist!" />
|
||||
<input id="welcomeFooter" placeholder="Schön, dass du da bist!" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
@@ -609,7 +609,7 @@ router.get('/', (req, res) => {
|
||||
<div class="embed-color" id="welcomePreviewColor"></div>
|
||||
<div class="embed-body">
|
||||
<div class="embed-title" id="welcomePreviewTitle">Willkommen!</div>
|
||||
<div class="embed-desc" id="welcomePreviewDesc">Schön, dass du da bist.</div>
|
||||
<div class="embed-desc" id="welcomePreviewDesc">Schön, dass du da bist.</div>
|
||||
<div class="embed-footer" id="welcomePreviewFooter">Footer</div>
|
||||
<img id="welcomePreviewImage" class="embed-image" style="display:none;" />
|
||||
</div>
|
||||
@@ -736,7 +736,7 @@ router.get('/', (req, res) => {
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label class="form-label">Eintraege (Emoji | Role ID | Label | Beschreibung)</label>
|
||||
<textarea id="reactionRoleEntries" rows="4" placeholder="😀 | 123456789 | Freunde | Erhaelt Freunde Rolle"></textarea>
|
||||
<textarea id="reactionRoleEntries" rows="4" placeholder="😀 | 123456789 | Freunde | Erhaelt Freunde Rolle"></textarea>
|
||||
<p class="muted">Eine Zeile pro Zuordnung. Label/Beschreibung optional.</p>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:flex-end; gap:10px;">
|
||||
@@ -810,7 +810,7 @@ router.get('/', (req, res) => {
|
||||
<section class="card">
|
||||
<div class="row" style="justify-content:space-between;">
|
||||
<div>
|
||||
<p class="section-title">Aktivität (letzte 24h)</p>
|
||||
<p class="section-title">Aktivität (letzte 24h)</p>
|
||||
<p class="section-sub">Events/Commands pro Stunde</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -820,7 +820,7 @@ router.get('/', (req, res) => {
|
||||
<div class="row" style="justify-content:space-between;">
|
||||
<div>
|
||||
<p class="section-title">Logs</p>
|
||||
<p class="section-sub">Neueste Einträge</p>
|
||||
<p class="section-sub">Neueste Einträge</p>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="log-list" id="adminLogs"></ul>
|
||||
@@ -847,13 +847,13 @@ router.get('/', (req, res) => {
|
||||
</div>
|
||||
</div>
|
||||
<div class="option-grid">
|
||||
<div class="option-card"><span>👋 User Join / Leave</span><div id="logJoinLeave" class="switch on"></div></div>
|
||||
<div class="option-card"><span>âœï¸ Message Edit</span><div id="logMsgEdit" class="switch on"></div></div>
|
||||
<div class="option-card"><span>ðŸ—‘ï¸ Message Delete</span><div id="logMsgDelete" class="switch on"></div></div>
|
||||
<div class="option-card"><span>ðŸ›¡ï¸ Automod Actions</span><div id="logAutomod" class="switch on"></div></div>
|
||||
<div class="option-card"><span>🎫 Ticket Actions</span><div id="logTickets" class="switch on"></div></div>
|
||||
<div class="option-card"><span>🎵 Musik-Events</span><div id="logMusic" class="switch on"></div></div>
|
||||
<div class="option-card"><span>âš™ï¸ System / Channels</span><div id="logSystem" class="switch on"></div></div>
|
||||
<div class="option-card"><span>👋 User Join / Leave</span><div id="logJoinLeave" class="switch on"></div></div>
|
||||
<div class="option-card"><span>✏️ Message Edit</span><div id="logMsgEdit" class="switch on"></div></div>
|
||||
<div class="option-card"><span>🗑️ Message Delete</span><div id="logMsgDelete" class="switch on"></div></div>
|
||||
<div class="option-card"><span>🛡️ Automod Actions</span><div id="logAutomod" class="switch on"></div></div>
|
||||
<div class="option-card"><span>🎫 Ticket Actions</span><div id="logTickets" class="switch on"></div></div>
|
||||
<div class="option-card"><span>🎵 Musik-Events</span><div id="logMusic" class="switch on"></div></div>
|
||||
<div class="option-card"><span>⚙️ System / Channels</span><div id="logSystem" class="switch on"></div></div>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:flex-end; gap:10px; margin-top:12px;">
|
||||
<button id="loggingSave" type="button">Logging speichern</button>
|
||||
@@ -1419,7 +1419,7 @@ router.get('/', (req, res) => {
|
||||
actions.className = 'row';
|
||||
const del = document.createElement('button');
|
||||
del.className = 'danger-btn';
|
||||
del.textContent = 'Löschen';
|
||||
del.textContent = 'Löschen';
|
||||
del.addEventListener('click', async () => {
|
||||
await deleteService(svc.id);
|
||||
});
|
||||
@@ -1477,7 +1477,7 @@ router.get('/', (req, res) => {
|
||||
if (res.ok) {
|
||||
await loadStatuspage();
|
||||
} else {
|
||||
showToast('Service löschen fehlgeschlagen', true);
|
||||
showToast('Service löschen fehlgeschlagen', true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1755,7 +1755,7 @@ router.get('/', (req, res) => {
|
||||
'</div>' +
|
||||
'<div class=\"ticket-meta\">User: ' +
|
||||
(t.userId || '-') +
|
||||
(t.claimedBy ? ' · Supporter: ' + t.claimedBy : '') +
|
||||
(t.claimedBy ? ' <EFBFBD> Supporter: ' + t.claimedBy : '') +
|
||||
'</div>';
|
||||
const select = document.createElement('select');
|
||||
select.innerHTML =
|
||||
@@ -1869,14 +1869,14 @@ router.get('/', (req, res) => {
|
||||
edit.addEventListener('click', () => fillAutomationForm(r));
|
||||
const del = document.createElement('button');
|
||||
del.className = 'danger-btn';
|
||||
del.textContent = 'Löschen';
|
||||
del.textContent = 'L<EFBFBD>schen';
|
||||
del.addEventListener('click', async () => {
|
||||
const res = await fetch('/api/automations/' + r.id, {
|
||||
method: 'DELETE',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ guildId: currentGuild })
|
||||
});
|
||||
showToast(res.ok ? 'Regel gelöscht' : 'Löschen fehlgeschlagen', !res.ok);
|
||||
showToast(res.ok ? 'Regel gel<EFBFBD>scht' : 'L<EFBFBD>schen fehlgeschlagen', !res.ok);
|
||||
if (res.ok) loadAutomations();
|
||||
});
|
||||
actions.appendChild(edit);
|
||||
@@ -1936,14 +1936,14 @@ router.get('/', (req, res) => {
|
||||
edit.addEventListener('click', () => fillKbForm(a));
|
||||
const del = document.createElement('button');
|
||||
del.className = 'danger-btn';
|
||||
del.textContent = 'Löschen';
|
||||
del.textContent = 'L<EFBFBD>schen';
|
||||
del.addEventListener('click', async () => {
|
||||
const res = await fetch('/api/kb/' + a.id, {
|
||||
method: 'DELETE',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ guildId: currentGuild })
|
||||
});
|
||||
showToast(res.ok ? 'Artikel gelöscht' : 'Löschen fehlgeschlagen', !res.ok);
|
||||
showToast(res.ok ? 'Artikel gel<EFBFBD>scht' : 'L<EFBFBD>schen fehlgeschlagen', !res.ok);
|
||||
if (res.ok) loadKb();
|
||||
});
|
||||
actions.appendChild(edit);
|
||||
@@ -2116,7 +2116,7 @@ router.get('/', (req, res) => {
|
||||
(s.userId || '-') +
|
||||
'</strong></div><div class="muted">Ende: ' +
|
||||
formatDate(s.endedAt || Date.now()) +
|
||||
' · Dauer: ' +
|
||||
' · Dauer: ' +
|
||||
dur +
|
||||
'</div>';
|
||||
supportRecentList.appendChild(div);
|
||||
@@ -2174,9 +2174,9 @@ router.get('/', (req, res) => {
|
||||
(ev.repeatType || 'none') +
|
||||
'</span></div><div class="ticket-meta">Start: ' +
|
||||
formatDate(ev.startTime) +
|
||||
' · Channel: ' +
|
||||
' · Channel: ' +
|
||||
(ev.channelId || '-') +
|
||||
' · Anmeldungen: ' +
|
||||
' · Anmeldungen: ' +
|
||||
(ev._count?.signups ?? 0) +
|
||||
'</div>';
|
||||
const actions = document.createElement('div');
|
||||
@@ -2389,7 +2389,7 @@ router.get('/', (req, res) => {
|
||||
meta.className = 'module-meta';
|
||||
const descParts = ['Channel: ' + (set.channelId || '-')];
|
||||
if (set.messageId) descParts.push('Message: ' + set.messageId);
|
||||
meta.innerHTML = '<div class="module-title">' + (set.title || 'Reaction Role') + '</div><div class="module-desc">' + descParts.join(' • ') + '</div>';
|
||||
meta.innerHTML = '<div class="module-title">' + (set.title || 'Reaction Role') + '</div><div class="module-desc">' + descParts.join(' • ') + '</div>';
|
||||
const actions = document.createElement('div');
|
||||
actions.className = 'row';
|
||||
const editBtn = document.createElement('button');
|
||||
@@ -2638,11 +2638,11 @@ router.get('/', (req, res) => {
|
||||
const actionType = document.getElementById('automationActionType')?.value;
|
||||
const actionVal = document.getElementById('automationActionValue')?.value;
|
||||
const active = getSwitch(document.getElementById('automationActive'));
|
||||
const condition: any = {};
|
||||
const condition = {};
|
||||
if (condType === 'category') condition.category = condVal;
|
||||
if (condType === 'status') condition.status = condVal;
|
||||
if (condType === 'age') condition.minHours = Number(condVal || 0);
|
||||
const action: any = { type: actionType };
|
||||
const action = { type: actionType };
|
||||
if (actionType === 'pingRole') action.roleId = actionVal;
|
||||
if (actionType === 'reminder') action.message = actionVal;
|
||||
if (actionType === 'flag') action.status = actionVal;
|
||||
|
||||
Reference in New Issue
Block a user