diff --git a/src/PostIt/PostIt/Controls/StatusBar.axaml b/src/PostIt/PostIt/Controls/StatusBar.axaml
new file mode 100644
index 000000000..eaa6f5a09
--- /dev/null
+++ b/src/PostIt/PostIt/Controls/StatusBar.axaml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
diff --git a/src/PostIt/PostIt/Controls/StatusBar.axaml.cs b/src/PostIt/PostIt/Controls/StatusBar.axaml.cs
new file mode 100644
index 000000000..975f9b2f9
--- /dev/null
+++ b/src/PostIt/PostIt/Controls/StatusBar.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace PostIt.Controls;
+
+public partial class StatusBar : UserControl
+{
+ public StatusBar()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/src/PostIt/PostIt/ViewModels/ActivitiesPageViewModel.cs b/src/PostIt/PostIt/ViewModels/ActivitiesPageViewModel.cs
index 2dc8938f3..801cf21d4 100644
--- a/src/PostIt/PostIt/ViewModels/ActivitiesPageViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/ActivitiesPageViewModel.cs
@@ -43,6 +43,14 @@ public partial class ActivitiesPageViewModel : ViewModelBase
[ObservableProperty]
public partial string StatusMessage { get; set; } = "Choisissez une activité.";
+ [ObservableProperty]
+ public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Choisissez une activité.");
+
+ partial void OnStatusMessageChanged(string value)
+ {
+ ActionStatus = StatusNotice.FromMessage(value);
+ }
+
public ActivityInfo? CurrentActivity => SelectedSpecialization ?? SelectedActivity;
public string SelectedActivityLabel => SelectedActivity?.Name ?? "(aucune activité)";
public string CurrentActivityLabel => CurrentActivity?.Name ?? "(aucune)";
diff --git a/src/PostIt/PostIt/ViewModels/CirclesPageViewModel.cs b/src/PostIt/PostIt/ViewModels/CirclesPageViewModel.cs
index 9cee3ea8c..6d70add1d 100644
--- a/src/PostIt/PostIt/ViewModels/CirclesPageViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/CirclesPageViewModel.cs
@@ -65,6 +65,14 @@ public partial class CirclesPageViewModel : ViewModelBase
[ObservableProperty]
public partial string StatusMessage { get; set; } = string.Empty;
+ [ObservableProperty]
+ public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
+
+ partial void OnStatusMessageChanged(string value)
+ {
+ ActionStatus = StatusNotice.FromMessage(value);
+ }
+
public CirclesPageViewModel(CircleApiClient client)
{
diff --git a/src/PostIt/PostIt/ViewModels/Commands/BillingCommandPageViewModel.cs b/src/PostIt/PostIt/ViewModels/Commands/BillingCommandPageViewModel.cs
index 0ab76291d..5fd7d8461 100644
--- a/src/PostIt/PostIt/ViewModels/Commands/BillingCommandPageViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/Commands/BillingCommandPageViewModel.cs
@@ -23,6 +23,9 @@ public abstract partial class BillingCommandPageViewModel : RemoteViewModelBase
[ObservableProperty]
public partial string StatusMessage { get; set; }
+ [ObservableProperty]
+ public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
+
[ObservableProperty]
public partial string Reason { get; set; } = string.Empty;
@@ -89,6 +92,11 @@ public abstract partial class BillingCommandPageViewModel : RemoteViewModelBase
OnPropertyChanged(nameof(CanUseCurrentLocation));
}
+ partial void OnStatusMessageChanged(string value)
+ {
+ ActionStatus = StatusNotice.FromMessage(value);
+ }
+
public async Task InitializeAsync(BillingQueryDetailsDto? existingQuery = null)
{
await LoadAsync();
diff --git a/src/PostIt/PostIt/ViewModels/Settings/Settings.cs b/src/PostIt/PostIt/ViewModels/Settings/Settings.cs
index e63f0b321..b59ef9933 100644
--- a/src/PostIt/PostIt/ViewModels/Settings/Settings.cs
+++ b/src/PostIt/PostIt/ViewModels/Settings/Settings.cs
@@ -31,6 +31,19 @@ public partial class Settings : ViewModelBase
[ObservableProperty]
public partial string SearchText { get; set; } = string.Empty;
+ [ObservableProperty]
+ public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
+
+ public void SetActionStatus(string message, StatusSeverity severity = StatusSeverity.Info)
+ {
+ ActionStatus = severity switch
+ {
+ StatusSeverity.Error => StatusNotice.Error(message),
+ StatusSeverity.Warning => StatusNotice.Warning(message),
+ _ => StatusNotice.Info(message),
+ };
+ }
+
///
/// Catch top-level mutations: the four ObservableProperty
/// setters above all funnel through here, and we flip
@@ -406,6 +419,8 @@ public partial class Settings : ViewModelBase
[RelayCommand(CanExecute = nameof(CanSave))]
public void Save()
{
+ SetActionStatus("Enregistrement des parametres...", StatusSeverity.Info);
+
var configDir = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"PostIt");
@@ -425,10 +440,13 @@ public partial class Settings : ViewModelBase
File.SetUnixFileMode(configPath,
UnixFileMode.UserRead | UnixFileMode.UserWrite);
IsDirty = false;
+ SetActionStatus("Parametres sauvegardes.", StatusSeverity.Info);
+
Console.WriteLine($"💾 Settings saved to {configPath}");
}
catch (Exception ex)
{
+ SetActionStatus($"Echec sauvegarde parametres: {ex.Message}", StatusSeverity.Error);
Console.Error.WriteLine($"🩎 Error saving settings to {configPath}: {ex.Message}");
throw;
}
diff --git a/src/PostIt/PostIt/ViewModels/StatusNotice.cs b/src/PostIt/PostIt/ViewModels/StatusNotice.cs
new file mode 100644
index 000000000..2d14b28b3
--- /dev/null
+++ b/src/PostIt/PostIt/ViewModels/StatusNotice.cs
@@ -0,0 +1,58 @@
+namespace PostIt.ViewModels;
+
+public enum StatusSeverity
+{
+ Info,
+ Warning,
+ Error
+}
+
+public sealed class StatusNotice
+{
+ public string Message { get; }
+ public StatusSeverity Severity { get; }
+ public string Glyph { get; }
+ public string Background { get; }
+ public string BorderBrush { get; }
+ public string Foreground { get; }
+
+ private StatusNotice(string message, StatusSeverity severity)
+ {
+ Message = string.IsNullOrWhiteSpace(message) ? "Pret." : message;
+ Severity = severity;
+
+ (Glyph, Background, BorderBrush, Foreground) = severity switch
+ {
+ StatusSeverity.Error => ("!", "#FDECEA", "#C62828", "#7F1D1D"),
+ StatusSeverity.Warning => ("~", "#FFF8E1", "#E6A700", "#7C4A03"),
+ _ => ("i", "#E8F0FE", "#5B8DEF", "#1E3A8A"),
+ };
+ }
+
+ public static StatusNotice Info(string message) => new(message, StatusSeverity.Info);
+ public static StatusNotice Warning(string message) => new(message, StatusSeverity.Warning);
+ public static StatusNotice Error(string message) => new(message, StatusSeverity.Error);
+
+ public static StatusNotice FromMessage(string? message)
+ {
+ if (string.IsNullOrWhiteSpace(message))
+ {
+ return Info("Pret.");
+ }
+
+ var text = message.Trim();
+ var lower = text.ToLowerInvariant();
+
+ if (lower.StartsWith("erreur") || lower.StartsWith("echec") || lower.StartsWith("impossible"))
+ {
+ return Error(text);
+ }
+
+ if (lower.Contains("refuse") || lower.Contains("annule") || lower.Contains("obligatoire") || lower.Contains("deja"))
+ {
+ return Warning(text);
+ }
+
+ return Info(text);
+ }
+}
diff --git a/src/PostIt/PostIt/Views/ActivitiesPage.axaml b/src/PostIt/PostIt/Views/ActivitiesPage.axaml
index 16d883443..a34d8edf2 100644
--- a/src/PostIt/PostIt/Views/ActivitiesPage.axaml
+++ b/src/PostIt/PostIt/Views/ActivitiesPage.axaml
@@ -1,6 +1,7 @@
-
+
diff --git a/src/PostIt/PostIt/Views/CirclesPage.axaml b/src/PostIt/PostIt/Views/CirclesPage.axaml
index 6fc2172ba..8488201e2 100644
--- a/src/PostIt/PostIt/Views/CirclesPage.axaml
+++ b/src/PostIt/PostIt/Views/CirclesPage.axaml
@@ -1,6 +1,7 @@
-
+
diff --git a/src/PostIt/PostIt/Views/Commands/RdvPage.axaml b/src/PostIt/PostIt/Views/Commands/RdvPage.axaml
index 46280602b..4c88b0108 100644
--- a/src/PostIt/PostIt/Views/Commands/RdvPage.axaml
+++ b/src/PostIt/PostIt/Views/Commands/RdvPage.axaml
@@ -1,6 +1,7 @@
@@ -71,16 +72,8 @@
Content="{Binding SubmitLabel}"
Command="{Binding SubmitCommand}"
IsEnabled="{Binding IsSupported}" />
-
+
-
+