mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
@@ -727,7 +727,8 @@
|
|||||||
"checkIntervalDesc": "How often to check for overdue tickets (30-600 seconds)",
|
"checkIntervalDesc": "How often to check for overdue tickets (30-600 seconds)",
|
||||||
"reminderCooldown": "Reminder interval (minutes)",
|
"reminderCooldown": "Reminder interval (minutes)",
|
||||||
"reminderCooldownDesc": "Minimum time between reminders (1-120 minutes)",
|
"reminderCooldownDesc": "Minimum time between reminders (1-120 minutes)",
|
||||||
"settingsUpdateError": "Error saving settings"
|
"settingsUpdateError": "Error saving settings",
|
||||||
|
"copyTelegramId": "Click to copy Telegram ID"
|
||||||
},
|
},
|
||||||
"tariffs": {
|
"tariffs": {
|
||||||
"title": "Tariff Management",
|
"title": "Tariff Management",
|
||||||
|
|||||||
@@ -727,7 +727,8 @@
|
|||||||
"checkIntervalDesc": "Как часто проверять просроченные тикеты (30-600 секунд)",
|
"checkIntervalDesc": "Как часто проверять просроченные тикеты (30-600 секунд)",
|
||||||
"reminderCooldown": "Интервал напоминаний (минуты)",
|
"reminderCooldown": "Интервал напоминаний (минуты)",
|
||||||
"reminderCooldownDesc": "Минимальное время между напоминаниями (1-120 минут)",
|
"reminderCooldownDesc": "Минимальное время между напоминаниями (1-120 минут)",
|
||||||
"settingsUpdateError": "Ошибка сохранения настроек"
|
"settingsUpdateError": "Ошибка сохранения настроек",
|
||||||
|
"copyTelegramId": "Нажмите чтобы скопировать Telegram ID"
|
||||||
},
|
},
|
||||||
"tariffs": {
|
"tariffs": {
|
||||||
"title": "Управление тарифами",
|
"title": "Управление тарифами",
|
||||||
|
|||||||
@@ -155,10 +155,21 @@ export default function AdminTickets() {
|
|||||||
|
|
||||||
const formatUser = (ticket: AdminTicket | AdminTicketDetail) => {
|
const formatUser = (ticket: AdminTicket | AdminTicketDetail) => {
|
||||||
if (!ticket.user) return 'Unknown'
|
if (!ticket.user) return 'Unknown'
|
||||||
const { first_name, last_name, username, telegram_id } = ticket.user
|
const { first_name, last_name, username } = ticket.user
|
||||||
if (first_name || last_name) return `${first_name || ''} ${last_name || ''}`.trim()
|
if (first_name || last_name) return `${first_name || ''} ${last_name || ''}`.trim()
|
||||||
if (username) return `@${username}`
|
if (username) return `@${username}`
|
||||||
return `ID: ${telegram_id}`
|
return 'User'
|
||||||
|
}
|
||||||
|
|
||||||
|
const copyToClipboard = (text: string) => {
|
||||||
|
navigator.clipboard.writeText(text).catch(() => {
|
||||||
|
const textarea = document.createElement('textarea')
|
||||||
|
textarea.value = text
|
||||||
|
document.body.appendChild(textarea)
|
||||||
|
textarea.select()
|
||||||
|
document.execCommand('copy')
|
||||||
|
document.body.removeChild(textarea)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -248,7 +259,17 @@ export default function AdminTickets() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-dark-500">
|
<div className="text-xs text-dark-500">
|
||||||
{formatUser(ticket)} | {new Date(ticket.updated_at).toLocaleDateString()}
|
{formatUser(ticket)}
|
||||||
|
{ticket.user?.telegram_id && (
|
||||||
|
<button
|
||||||
|
onClick={(e) => { e.stopPropagation(); copyToClipboard(String(ticket.user!.telegram_id)) }}
|
||||||
|
className="ml-1 text-dark-600 hover:text-accent-400 transition-colors"
|
||||||
|
title={t('admin.tickets.copyTelegramId')}
|
||||||
|
>
|
||||||
|
(TG: {ticket.user!.telegram_id})
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{' '}| {new Date(ticket.updated_at).toLocaleDateString()}
|
||||||
</div>
|
</div>
|
||||||
{ticket.last_message && (
|
{ticket.last_message && (
|
||||||
<div className="text-xs text-dark-600 mt-1 truncate">
|
<div className="text-xs text-dark-600 mt-1 truncate">
|
||||||
@@ -315,8 +336,17 @@ export default function AdminTickets() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm text-dark-500 mb-4">
|
<div className="text-sm text-dark-500 mb-4">
|
||||||
{t('admin.tickets.from')}: {formatUser(selectedTicket)} |{' '}
|
{t('admin.tickets.from')}: {formatUser(selectedTicket)}
|
||||||
{t('admin.tickets.created')}: {new Date(selectedTicket.created_at).toLocaleString()}
|
{selectedTicket.user?.telegram_id && (
|
||||||
|
<button
|
||||||
|
onClick={() => copyToClipboard(String(selectedTicket.user!.telegram_id))}
|
||||||
|
className="ml-1 px-2 py-0.5 text-xs bg-dark-700 hover:bg-dark-600 rounded transition-colors"
|
||||||
|
title={t('admin.tickets.copyTelegramId')}
|
||||||
|
>
|
||||||
|
TG: {selectedTicket.user!.telegram_id}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{' '}| {t('admin.tickets.created')}: {new Date(selectedTicket.created_at).toLocaleString()}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
{['open', 'pending', 'answered', 'closed'].map((s) => (
|
{['open', 'pending', 'answered', 'closed'].map((s) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user