избавление от вложенности управления администраторов
This commit is contained in:
parent
33b4ab1ce5
commit
7ec5f86557
411
Program.cs
411
Program.cs
@ -158,19 +158,6 @@ class Program
|
|||||||
await SendMainMenu(botClient, chatId);
|
await SendMainMenu(botClient, chatId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (data == "view_admins")
|
|
||||||
{
|
|
||||||
if (admins.Contains(chatId))
|
|
||||||
{
|
|
||||||
await ShowAdminsList(botClient, chatId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await botClient.SendMessage(chatId, "⛔ У вас нет прав для просмотра администраторов!");
|
|
||||||
await Task.Delay(2000);
|
|
||||||
await SendMainMenu(botClient, chatId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (data != null && data.StartsWith("removeadmin_"))
|
else if (data != null && data.StartsWith("removeadmin_"))
|
||||||
{
|
{
|
||||||
long adminIdToRemove = long.Parse(data.Substring(11).Replace("_", ""));
|
long adminIdToRemove = long.Parse(data.Substring(11).Replace("_", ""));
|
||||||
@ -251,153 +238,153 @@ class Program
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (data == "admin_panel")
|
else if (data == "admin_panel")
|
||||||
{
|
|
||||||
if (admins.Contains(chatId))
|
|
||||||
{
|
{
|
||||||
await SendAdminPanel(botClient, chatId);
|
if (admins.Contains(chatId))
|
||||||
|
{
|
||||||
|
await SendAdminPanel(botClient, chatId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var authMessage = await botClient.SendMessage(chatId, "⛔ Вы не являетесь администратором!");
|
||||||
|
Log.Information($"Неавторизованный доступ к админ-панели от {chatId}");
|
||||||
|
await Task.Delay(2000);
|
||||||
|
await botClient.DeleteMessage(chatId, authMessage.MessageId);
|
||||||
|
await SendMainMenu(botClient, chatId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (data == "view_reports")
|
||||||
{
|
{
|
||||||
var authMessage = await botClient.SendMessage(chatId, "⛔ Вы не являетесь администратором!");
|
if (admins.Contains(chatId))
|
||||||
Log.Information($"Неавторизованный доступ к админ-панели от {chatId}");
|
{
|
||||||
await Task.Delay(2000);
|
await ViewReports(botClient, chatId);
|
||||||
await botClient.DeleteMessage(chatId, authMessage.MessageId);
|
}
|
||||||
await SendMainMenu(botClient, chatId);
|
else
|
||||||
|
{
|
||||||
|
var authMessage = await botClient.SendMessage(chatId, "⛔ Вы не являетесь администратором!");
|
||||||
|
Log.Information($"Неавторизованный доступ к заявкам от {chatId}");
|
||||||
|
await Task.Delay(2000);
|
||||||
|
await botClient.DeleteMessage(chatId, authMessage.MessageId);
|
||||||
|
await SendMainMenu(botClient, chatId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else if (data == "view_archived_reports")
|
||||||
else if (data == "view_reports")
|
{
|
||||||
{
|
if (admins.Contains(chatId))
|
||||||
if (admins.Contains(chatId))
|
{
|
||||||
|
await ViewArchivedReports(botClient, chatId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var authMessage = await botClient.SendMessage(chatId, "⛔ Вы не являетесь администратором!");
|
||||||
|
Log.Information($"Неавторизованный доступ к архиву заявок от {chatId}");
|
||||||
|
await Task.Delay(2000);
|
||||||
|
await botClient.DeleteMessage(chatId, authMessage.MessageId);
|
||||||
|
await SendMainMenu(botClient, chatId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (data != null && data.StartsWith("report_"))
|
||||||
|
{
|
||||||
|
long reportId = long.Parse(data.Substring(7));
|
||||||
|
if (callbackQuery?.Message?.MessageId != null)
|
||||||
|
{
|
||||||
|
int messageId = callbackQuery.Message.MessageId;
|
||||||
|
await ShowReportDetails(botClient, chatId, reportId, messageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (data != null && data.StartsWith("status_"))
|
||||||
|
{
|
||||||
|
string[] parts = data.Split('_');
|
||||||
|
long reportId = long.Parse(parts[1]);
|
||||||
|
string newStatus = parts[2];
|
||||||
|
if (callbackQuery?.Message?.MessageId != null)
|
||||||
|
{
|
||||||
|
int messageId = callbackQuery.Message.MessageId;
|
||||||
|
await UpdateReportStatus(reportId, newStatus, chatId);
|
||||||
|
await ShowReportDetails(botClient, chatId, reportId, messageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (data != null && data.StartsWith("delete_"))
|
||||||
|
{
|
||||||
|
long reportId = long.Parse(data.Substring(7));
|
||||||
|
await DeleteReport(botClient, chatId, reportId);
|
||||||
|
}
|
||||||
|
else if (data == "back_to_list")
|
||||||
{
|
{
|
||||||
await ViewReports(botClient, chatId);
|
await ViewReports(botClient, chatId);
|
||||||
}
|
}
|
||||||
else
|
else if (data == "back_to_admin_panel")
|
||||||
|
{
|
||||||
|
await SendAdminPanel(botClient, chatId);
|
||||||
|
}
|
||||||
|
else if (data == "main_menu")
|
||||||
{
|
{
|
||||||
var authMessage = await botClient.SendMessage(chatId, "⛔ Вы не являетесь администратором!");
|
|
||||||
Log.Information($"Неавторизованный доступ к заявкам от {chatId}");
|
|
||||||
await Task.Delay(2000);
|
|
||||||
await botClient.DeleteMessage(chatId, authMessage.MessageId);
|
|
||||||
await SendMainMenu(botClient, chatId);
|
await SendMainMenu(botClient, chatId);
|
||||||
}
|
}
|
||||||
}
|
else if (data != null && data.StartsWith("priority_"))
|
||||||
else if (data == "view_archived_reports")
|
|
||||||
{
|
|
||||||
if (admins.Contains(chatId))
|
|
||||||
{
|
{
|
||||||
await ViewArchivedReports(botClient, chatId);
|
string priority = data.Substring(9);
|
||||||
|
userReports[chatId].Priority = priority;
|
||||||
|
userReportSteps[chatId] = 2;
|
||||||
|
await botClient.SendMessage(chatId, "Пожалуйста, укажите кабинет.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обработка текстовых сообщений
|
||||||
|
if (update.Type == UpdateType.Message && update.Message?.Text != null)
|
||||||
|
{
|
||||||
|
var message = update.Message;
|
||||||
|
Log.Information($"Получено сообщение от {message.Chat.Id}: {message.Text}");
|
||||||
|
|
||||||
|
if (message.Text.StartsWith("/admin"))
|
||||||
|
{
|
||||||
|
string[] parts = message.Text.Split(' ');
|
||||||
|
if (parts.Length == 2 && parts[1] == adminPassword)
|
||||||
|
{
|
||||||
|
admins.Add(message.Chat.Id);
|
||||||
|
// Сохраняем администратора в базу данных
|
||||||
|
await SaveAdminToDatabase(message.Chat.Id);
|
||||||
|
|
||||||
|
var authMessage = await botClient.SendMessage(message.Chat.Id, "✅ Вы авторизованы как администратор!");
|
||||||
|
Log.Information($"Новый администратор: {message.Chat.Id}");
|
||||||
|
await Task.Delay(2000);
|
||||||
|
await botClient.DeleteMessage(message.Chat.Id, authMessage.MessageId);
|
||||||
|
await SendMainMenu(botClient, message.Chat.Id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var authMessage = await botClient.SendMessage(chatId, "⛔ Вы не являетесь администратором!");
|
var authMessage = await botClient.SendMessage(message.Chat.Id, "❌ Неверный пароль!");
|
||||||
Log.Information($"Неавторизованный доступ к архиву заявок от {chatId}");
|
|
||||||
await Task.Delay(2000);
|
await Task.Delay(2000);
|
||||||
await botClient.DeleteMessage(chatId, authMessage.MessageId);
|
await botClient.DeleteMessage(message.Chat.Id, authMessage.MessageId);
|
||||||
await SendMainMenu(botClient, chatId);
|
await SendMainMenu(botClient, message.Chat.Id);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (data != null && data.StartsWith("report_"))
|
|
||||||
|
// В блоке для обработки текстовых сообщений
|
||||||
|
else if (message.Text == "/admins")
|
||||||
{
|
{
|
||||||
long reportId = long.Parse(data.Substring(7));
|
if (admins.Contains(message.Chat.Id))
|
||||||
if (callbackQuery?.Message?.MessageId != null)
|
|
||||||
{
|
{
|
||||||
int messageId = callbackQuery.Message.MessageId;
|
await ShowAdminsList(botClient, message.Chat.Id);
|
||||||
await ShowReportDetails(botClient, chatId, reportId, messageId);
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else if (data != null && data.StartsWith("status_"))
|
|
||||||
{
|
|
||||||
string[] parts = data.Split('_');
|
|
||||||
long reportId = long.Parse(parts[1]);
|
|
||||||
string newStatus = parts[2];
|
|
||||||
if (callbackQuery?.Message?.MessageId != null)
|
|
||||||
{
|
{
|
||||||
int messageId = callbackQuery.Message.MessageId;
|
var authMessage = await botClient.SendMessage(
|
||||||
await UpdateReportStatus(reportId, newStatus, chatId);
|
chatId: message.Chat.Id,
|
||||||
await ShowReportDetails(botClient, chatId, reportId, messageId);
|
text: "⛔ У вас нет прав для просмотра списка администраторов!"
|
||||||
|
);
|
||||||
|
await Task.Delay(2000);
|
||||||
|
await botClient.DeleteMessage(message.Chat.Id, authMessage.MessageId);
|
||||||
|
await SendMainMenu(botClient, message.Chat.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (data != null && data.StartsWith("delete_"))
|
|
||||||
{
|
|
||||||
long reportId = long.Parse(data.Substring(7));
|
|
||||||
await DeleteReport(botClient, chatId, reportId);
|
|
||||||
}
|
|
||||||
else if (data == "back_to_list")
|
|
||||||
{
|
|
||||||
await ViewReports(botClient, chatId);
|
|
||||||
}
|
|
||||||
else if (data == "back_to_admin_panel")
|
|
||||||
{
|
|
||||||
await SendAdminPanel(botClient, chatId);
|
|
||||||
}
|
|
||||||
else if (data == "main_menu")
|
|
||||||
{
|
|
||||||
await SendMainMenu(botClient, chatId);
|
|
||||||
}
|
|
||||||
else if (data != null && data.StartsWith("priority_"))
|
|
||||||
{
|
|
||||||
string priority = data.Substring(9);
|
|
||||||
userReports[chatId].Priority = priority;
|
|
||||||
userReportSteps[chatId] = 2;
|
|
||||||
await botClient.SendMessage(chatId, "Пожалуйста, укажите кабинет.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка текстовых сообщений
|
if (message.Text == "/start")
|
||||||
if (update.Type == UpdateType.Message && update.Message?.Text != null)
|
|
||||||
{
|
|
||||||
var message = update.Message;
|
|
||||||
Log.Information($"Получено сообщение от {message.Chat.Id}: {message.Text}");
|
|
||||||
|
|
||||||
if (message.Text.StartsWith("/admin"))
|
|
||||||
{
|
|
||||||
string[] parts = message.Text.Split(' ');
|
|
||||||
if (parts.Length == 2 && parts[1] == adminPassword)
|
|
||||||
{
|
|
||||||
admins.Add(message.Chat.Id);
|
|
||||||
// Сохраняем администратора в базу данных
|
|
||||||
await SaveAdminToDatabase(message.Chat.Id);
|
|
||||||
|
|
||||||
var authMessage = await botClient.SendMessage(message.Chat.Id, "✅ Вы авторизованы как администратор!");
|
|
||||||
Log.Information($"Новый администратор: {message.Chat.Id}");
|
|
||||||
await Task.Delay(2000);
|
|
||||||
await botClient.DeleteMessage(message.Chat.Id, authMessage.MessageId);
|
|
||||||
await SendMainMenu(botClient, message.Chat.Id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var authMessage = await botClient.SendMessage(message.Chat.Id, "❌ Неверный пароль!");
|
|
||||||
await Task.Delay(2000);
|
|
||||||
await botClient.DeleteMessage(message.Chat.Id, authMessage.MessageId);
|
|
||||||
await SendMainMenu(botClient, message.Chat.Id);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// В блоке для обработки текстовых сообщений
|
|
||||||
else if (message.Text == "/admins")
|
|
||||||
{
|
|
||||||
if (admins.Contains(message.Chat.Id))
|
|
||||||
{
|
|
||||||
await ShowAdminsList(botClient, message.Chat.Id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var authMessage = await botClient.SendMessage(
|
|
||||||
chatId: message.Chat.Id,
|
|
||||||
text: "⛔ У вас нет прав для просмотра списка администраторов!"
|
|
||||||
);
|
|
||||||
await Task.Delay(2000);
|
|
||||||
await botClient.DeleteMessage(message.Chat.Id, authMessage.MessageId);
|
|
||||||
await SendMainMenu(botClient, message.Chat.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.Text == "/start")
|
|
||||||
{
|
|
||||||
var keyboard = new InlineKeyboardMarkup(new[]
|
|
||||||
{
|
{
|
||||||
|
var keyboard = new InlineKeyboardMarkup(new[]
|
||||||
|
{
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
InlineKeyboardButton.WithCallbackData("Подать заявку", "report"),
|
InlineKeyboardButton.WithCallbackData("Подать заявку", "report"),
|
||||||
@ -405,55 +392,56 @@ class Program
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await botClient.SendMessage(
|
await botClient.SendMessage(
|
||||||
chatId: message.Chat.Id,
|
chatId: message.Chat.Id,
|
||||||
text: "Привет! Я бот для сбора заявок на ремонт оборудования.",
|
text: "Привет! Я бот для сбора заявок на ремонт оборудования.",
|
||||||
replyMarkup: keyboard
|
replyMarkup: keyboard
|
||||||
);
|
);
|
||||||
Log.Information($"Ответ на команду /start с кнопками отправлен.");
|
Log.Information($"Ответ на команду /start с кнопками отправлен.");
|
||||||
}
|
}
|
||||||
else if (usersWaitingForReport.TryGetValue(message.Chat.Id, out bool isWaiting) && isWaiting)
|
else if (usersWaitingForReport.TryGetValue(message.Chat.Id, out bool isWaiting) && isWaiting)
|
||||||
{
|
|
||||||
if (userReportSteps.TryGetValue(message.Chat.Id, out int step))
|
|
||||||
{
|
{
|
||||||
switch (step)
|
if (userReportSteps.TryGetValue(message.Chat.Id, out int step))
|
||||||
{
|
{
|
||||||
case 2:
|
switch (step)
|
||||||
userReports[message.Chat.Id].Room = message.Text;
|
{
|
||||||
userReportSteps[message.Chat.Id] = 3;
|
case 2:
|
||||||
await botClient.SendMessage(message.Chat.Id, "Пожалуйста, опишите проблему.");
|
userReports[message.Chat.Id].Room = message.Text;
|
||||||
break;
|
userReportSteps[message.Chat.Id] = 3;
|
||||||
case 3:
|
await botClient.SendMessage(message.Chat.Id, "Пожалуйста, опишите проблему.");
|
||||||
userReports[message.Chat.Id].Description = message.Text;
|
break;
|
||||||
userReportSteps[message.Chat.Id] = 4;
|
case 3:
|
||||||
await botClient.SendMessage(message.Chat.Id, "Пожалуйста, укажите ваше ФИО.");
|
userReports[message.Chat.Id].Description = message.Text;
|
||||||
break;
|
userReportSteps[message.Chat.Id] = 4;
|
||||||
case 4:
|
await botClient.SendMessage(message.Chat.Id, "Пожалуйста, укажите ваше ФИО.");
|
||||||
userReports[message.Chat.Id].ReporterName = message.Text;
|
break;
|
||||||
await SaveReportToDatabase(message.Chat.Id, userReports[message.Chat.Id]);
|
case 4:
|
||||||
var mainMenuKeyboard = new InlineKeyboardMarkup(new[]
|
userReports[message.Chat.Id].ReporterName = message.Text;
|
||||||
{
|
await SaveReportToDatabase(message.Chat.Id, userReports[message.Chat.Id]);
|
||||||
|
var mainMenuKeyboard = new InlineKeyboardMarkup(new[]
|
||||||
|
{
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
InlineKeyboardButton.WithCallbackData("Главное меню", "main_menu")
|
InlineKeyboardButton.WithCallbackData("Главное меню", "main_menu")
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await botClient.SendMessage(
|
await botClient.SendMessage(
|
||||||
message.Chat.Id,
|
message.Chat.Id,
|
||||||
"✅ Спасибо за заявку! Мы обработаем её в ближайшее время.",
|
"✅ Спасибо за заявку! Мы обработаем её в ближайшее время.",
|
||||||
replyMarkup: mainMenuKeyboard
|
replyMarkup: mainMenuKeyboard
|
||||||
);
|
);
|
||||||
usersWaitingForReport[message.Chat.Id] = false;
|
usersWaitingForReport[message.Chat.Id] = false;
|
||||||
userReportSteps.Remove(message.Chat.Id);
|
userReportSteps.Remove(message.Chat.Id);
|
||||||
userReports.Remove(message.Chat.Id);
|
userReports.Remove(message.Chat.Id);
|
||||||
Log.Information($"Заявка пользователя {message.Chat.Id} сохранена в базе данных.");
|
Log.Information($"Заявка пользователя {message.Chat.Id} сохранена в базе данных.");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
await botClient.SendMessage(message.Chat.Id, "ℹ️ Используйте команду /start для начала работы с ботом.");
|
||||||
await botClient.SendMessage(message.Chat.Id, "ℹ️ Используйте команду /start для начала работы с ботом.");
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -866,20 +854,73 @@ class Program
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var keyboard = new InlineKeyboardMarkup(new[]
|
// Получаем список всех администраторов из базы данных
|
||||||
|
var adminsList = new List<(long chatId, string username)>();
|
||||||
|
|
||||||
|
using (var connection = new SqliteConnection("Data Source=bot.db"))
|
||||||
{
|
{
|
||||||
new[] {
|
await connection.OpenAsync();
|
||||||
InlineKeyboardButton.WithCallbackData("👥 Список администраторов", "view_admins")
|
var command = connection.CreateCommand();
|
||||||
},
|
command.CommandText = "SELECT ChatId FROM Admins";
|
||||||
new[] {
|
|
||||||
InlineKeyboardButton.WithCallbackData("🔙 Назад к панели администратора", "admin_panel"),
|
using (var reader = await command.ExecuteReaderAsync())
|
||||||
InlineKeyboardButton.WithCallbackData("🏠 Главное меню", "main_menu")
|
{
|
||||||
|
while (await reader.ReadAsync())
|
||||||
|
{
|
||||||
|
long adminId = reader.GetInt64(0);
|
||||||
|
string username = "Неизвестно";
|
||||||
|
|
||||||
|
// Пытаемся получить имя пользователя
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var user = await botClient.GetChat(adminId);
|
||||||
|
username = user.Username ?? user.FirstName ?? "Неизвестно";
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Если возникает ошибка при получении информации о пользователе,
|
||||||
|
// просто используем "Неизвестно"
|
||||||
|
}
|
||||||
|
|
||||||
|
adminsList.Add((adminId, username));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Формируем сообщение
|
||||||
|
if (adminsList.Count == 0)
|
||||||
|
{
|
||||||
|
await botClient.SendMessage(
|
||||||
|
chatId: chatId,
|
||||||
|
text: "⚠️ В системе нет зарегистрированных администраторов."
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var buttons = new List<InlineKeyboardButton[]>();
|
||||||
|
var messageText = new System.Text.StringBuilder();
|
||||||
|
messageText.AppendLine("📋 <b>Список администраторов:</b>\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < adminsList.Count; i++)
|
||||||
|
{
|
||||||
|
var (adminId, username) = adminsList[i];
|
||||||
|
messageText.AppendLine($"{i + 1}. {username} (ID: {adminId})");
|
||||||
|
|
||||||
|
buttons.Add(new[] {
|
||||||
|
InlineKeyboardButton.WithCallbackData($"❌ Удалить {username}", $"removeadmin_{adminId}")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons.Add(new[] {
|
||||||
|
InlineKeyboardButton.WithCallbackData("🔙 Назад", "admin_panel"),
|
||||||
|
InlineKeyboardButton.WithCallbackData("🏠 Главное меню", "main_menu")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var keyboard = new InlineKeyboardMarkup(buttons);
|
||||||
|
|
||||||
await botClient.SendMessage(
|
await botClient.SendMessage(
|
||||||
chatId: chatId,
|
chatId: chatId,
|
||||||
text: "⚙️ <b>Управление администраторами</b>",
|
text: messageText.ToString(),
|
||||||
parseMode: ParseMode.Html,
|
parseMode: ParseMode.Html,
|
||||||
replyMarkup: keyboard
|
replyMarkup: keyboard
|
||||||
);
|
);
|
||||||
@ -887,6 +928,10 @@ class Program
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error($"Ошибка при отображении настроек администраторов: {ex.Message}");
|
Log.Error($"Ошибка при отображении настроек администраторов: {ex.Message}");
|
||||||
|
await botClient.SendMessage(
|
||||||
|
chatId: chatId,
|
||||||
|
text: "❌ Произошла ошибка при отображении настроек администраторов."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user