diff --git a/Content.Client/Administration/UI/Tabs/AdminTab/AdminTab.xaml b/Content.Client/Administration/UI/Tabs/AdminTab/AdminTab.xaml
index 32ef267ba8..083d214773 100644
--- a/Content.Client/Administration/UI/Tabs/AdminTab/AdminTab.xaml
+++ b/Content.Client/Administration/UI/Tabs/AdminTab/AdminTab.xaml
@@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
xmlns:at="clr-namespace:Content.Client.Administration.UI.Tabs.AdminTab"
+ xmlns:wd="clr-namespace:Content.Client._White.Administration"
Margin="4"
MinSize="50 50">
@@ -18,6 +19,7 @@
+
diff --git a/Content.Client/_White/Administration/HoursPanel.xaml b/Content.Client/_White/Administration/HoursPanel.xaml
new file mode 100644
index 0000000000..6ea7218d98
--- /dev/null
+++ b/Content.Client/_White/Administration/HoursPanel.xaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/_White/Administration/HoursPanel.xaml.cs b/Content.Client/_White/Administration/HoursPanel.xaml.cs
new file mode 100644
index 0000000000..c51cedc28d
--- /dev/null
+++ b/Content.Client/_White/Administration/HoursPanel.xaml.cs
@@ -0,0 +1,104 @@
+using Content.Shared.Administration;
+using Content.Shared.Roles;
+using JetBrains.Annotations;
+using Robust.Client.AutoGenerated;
+using Robust.Client.Console;
+using Robust.Client.UserInterface.CustomControls;
+using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Prototypes;
+using static Robust.Client.UserInterface.Controls.LineEdit;
+
+namespace Content.Client._White.Administration;
+
+[GenerateTypedNameReferences]
+[UsedImplicitly]
+public sealed partial class HoursPanel : DefaultWindow
+{
+ public HoursPanel()
+ {
+ RobustXamlLoader.Load(this);
+ var roles = new Dictionary();
+ PlayerNameLine.OnTextChanged += _ => OnNamesChanged();
+ PlayerList.OnSelectionChanged += OnPlayerSelectionChanged;
+ HourButton.OnPressed += _ => AddMinutes(60);
+ MinutesLine.OnTextChanged += UpdateButtonsText;
+ RoleOption.OnItemSelected += args => RoleOption.SelectId(args.Id);
+ SubmitButton.OnPressed += _ => OnSubmitButtonOnPressed(roles);
+ SaveButton.OnPressed += _ => OnSaveButtonOnPressed();
+ OnNamesChanged();
+ InitRoleList(roles);
+
+ }
+ private void InitRoleList(Dictionary roles)
+ {
+ var roleInd = 0;
+ RoleOption.AddItem("общее", roleInd);
+ roles.Add(roleInd, "Overall");
+ roleInd++;
+ foreach (var dep in IoCManager.Resolve().EnumeratePrototypes())
+ {
+ foreach (var role in dep.Roles)
+ {
+ RoleOption.AddItem(Loc.GetString($"Job{role.Id}"), roleInd);
+ roles.Add(roleInd, $"Job{role.Id}");
+ roleInd++;
+ }
+ }
+ RoleOption.SelectId(0);
+ }
+
+ private bool TryGetMinutes(string str, out uint minutes)
+ {
+ minutes = 0;
+ return !string.IsNullOrWhiteSpace(str) && uint.TryParse(str, out minutes);
+ }
+
+ private void AddMinutes(uint add)
+ {
+ if (!TryGetMinutes(MinutesLine.Text, out var minutes))
+ minutes = 0;
+
+ MinutesLine.Text = $"{minutes + add}";
+ UpdateButtons(minutes + add);
+ OnNamesChanged();
+ }
+
+ private void UpdateButtonsText(LineEditEventArgs obj)
+ {
+ if (!TryGetMinutes(obj.Text, out var minutes))
+ return;
+
+ UpdateButtons(minutes);
+ OnNamesChanged();
+ }
+
+ private void UpdateButtons(uint minutes)
+ {
+ HourButton.Text = $"+1h ({minutes / 60})";
+ }
+
+ private void OnNamesChanged()
+ {
+ SubmitButton.Disabled = string.IsNullOrEmpty(PlayerNameLine.Text) || !TryGetMinutes(MinutesLine.Text, out _);
+ }
+
+ private void OnPlayerSelectionChanged(PlayerInfo? player)
+ {
+ PlayerNameLine.Text = player?.Username ?? string.Empty;
+ OnNamesChanged();
+ }
+
+ private void OnSubmitButtonOnPressed(Dictionary roles)
+ {
+ IoCManager.Resolve().ExecuteCommand(
+ $"playtime_addrole {PlayerNameLine.Text} {roles[RoleOption.SelectedId]} {MinutesLine.Text}");
+ SaveButton.Disabled = false;
+ }
+
+ private void OnSaveButtonOnPressed()
+ {
+ IoCManager.Resolve().ExecuteCommand(
+ $"playtime_save {PlayerNameLine.Text}");
+ SaveButton.Disabled = true;
+ }
+}
diff --git a/Content.Server/Administration/Commands/PlayTimeCommands.cs b/Content.Server/Administration/Commands/PlayTimeCommands.cs
index dd64528a93..5dbbc5b25f 100644
--- a/Content.Server/Administration/Commands/PlayTimeCommands.cs
+++ b/Content.Server/Administration/Commands/PlayTimeCommands.cs
@@ -93,7 +93,7 @@ public sealed class PlayTimeAddRoleCommand : IConsoleCommand
}
_playTimeTracking.AddTimeToTracker(player, role, TimeSpan.FromMinutes(minutes));
- var time = _playTimeTracking.GetOverallPlaytime(player);
+ var time = _playTimeTracking.GetPlayTimeForTracker(player, role);
shell.WriteLine(Loc.GetString("cmd-playtime_addrole-succeed",
("username", userName),
("role", role),
diff --git a/Resources/Locale/ru-RU/job/job-names.ftl b/Resources/Locale/ru-RU/job/job-names.ftl
index 4e8ec08c20..6c0d39b275 100644
--- a/Resources/Locale/ru-RU/job/job-names.ftl
+++ b/Resources/Locale/ru-RU/job/job-names.ftl
@@ -56,6 +56,7 @@ job-name-bomzh = бомж
# Role timers - Make these alphabetical or I cut you
JobAtmosphericTechnician = атмосферный техник
JobBartender = бармен
+JobBomzh = бомж
JobBorg = борг
JobBotanist = ботаник
JobBoxer = боксер
@@ -69,7 +70,7 @@ JobChiefEngineer = старший инженер
JobChiefMedicalOfficer = главный врач
JobClown = клоун
JobDetective = детектив
-JobBrigmedic = Бригмедик
+JobBrigmedic = бригмедик
JobERTEngineer = инженер ОБР
JobERTJanitor = уборщик ОБР
JobERTLeader = лидер ОБР
@@ -77,9 +78,11 @@ JobERTMedical = медик ОБР
JobERTSecurity = офицер безопасности ОБР
JobHeadOfPersonnel = глава персонала
JobHeadOfSecurity = глава службы безопасности
+JobInspector = инспектор
JobJanitor = уборщик
JobLawyer = юрист
JobLibrarian = библиотекарь
+JobMaid = прислуга
JobMedicalDoctor = врач
JobMedicalIntern = интерн
JobMime = мим
@@ -105,3 +108,4 @@ JobStationEngineer = инженер
JobTechnicalAssistant = технический ассистент
JobWarden = смотритель
JobZookeeper = зоотехник
+JobVisitor = посетитель
diff --git a/Resources/Locale/ru-RU/players/play-time/play-time-commands.ftl b/Resources/Locale/ru-RU/players/play-time/play-time-commands.ftl
index 427d2702c6..7ab62302b6 100644
--- a/Resources/Locale/ru-RU/players/play-time/play-time-commands.ftl
+++ b/Resources/Locale/ru-RU/players/play-time/play-time-commands.ftl
@@ -6,14 +6,14 @@ parse-session-fail = Не найдена сессия для '{ $username }'
# - playtime_addoverall
cmd-playtime_addoverall-desc = Добавляет указанное число минут к общему игровому времени игрока
cmd-playtime_addoverall-help = Использование: { $command }
-cmd-playtime_addoverall-succeed = Общее игровое время { $username } увеличено на { TOSTRING($time, "dddd\\:hh\\:mm") }.
+cmd-playtime_addoverall-succeed = Общее игровое время { $username } увеличено до { TOSTRING($time, "dddd\\:hh\\:mm") }.
cmd-playtime_addoverall-arg-user =
cmd-playtime_addoverall-arg-minutes =
cmd-playtime_addoverall-error-args = Ожидается ровно два аргумента
# - playtime_addrole
cmd-playtime_addrole-desc = Добавляет указанное число минут к времени игрока на определённой роли
cmd-playtime_addrole-help = Использование: { $command }
-cmd-playtime_addrole-succeed = Игровое время для { $username } / \'{ $role }\' увеличено на { TOSTRING($time, "dddd\\:hh\\:mm") }.
+cmd-playtime_addrole-succeed = Игровое время для { $username } / \'{ $role }\' увеличено до { TOSTRING($time, "dddd\\:hh\\:mm") }.
cmd-playtime_addrole-arg-user =
cmd-playtime_addrole-arg-role =
cmd-playtime_addrole-arg-minutes =
diff --git a/Resources/Locale/ru-RU/ui/misc.ftl b/Resources/Locale/ru-RU/ui/misc.ftl
new file mode 100644
index 0000000000..daae4e3f54
--- /dev/null
+++ b/Resources/Locale/ru-RU/ui/misc.ftl
@@ -0,0 +1 @@
+Filter = Фильтр