diff --git a/.gitignore b/.gitignore
index 017d140..5592f77 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@ obj/
.vs/
.idea/
*.user
-*.suo
\ No newline at end of file
+*.suo
+./Clario/CLAUDE_CONTEXT.md
\ No newline at end of file
diff --git a/Clario.Android/Clario.Android.csproj b/Clario.Android/Clario.Android.csproj
index bd7e303..a97e0a7 100644
--- a/Clario.Android/Clario.Android.csproj
+++ b/Clario.Android/Clario.Android.csproj
@@ -15,10 +15,13 @@
+
+
+
diff --git a/Clario.Browser/Clario.Browser.csproj b/Clario.Browser/Clario.Browser.csproj
index 9a83c58..49cb37a 100644
--- a/Clario.Browser/Clario.Browser.csproj
+++ b/Clario.Browser/Clario.Browser.csproj
@@ -8,15 +8,18 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
diff --git a/Clario.Desktop/Clario.Desktop.csproj b/Clario.Desktop/Clario.Desktop.csproj
index 484e86d..41f803f 100644
--- a/Clario.Desktop/Clario.Desktop.csproj
+++ b/Clario.Desktop/Clario.Desktop.csproj
@@ -3,6 +3,7 @@
WinExe
net8.0
enable
+ true
@@ -10,6 +11,7 @@
+
@@ -20,6 +22,7 @@
+
diff --git a/Clario.Desktop/Clario.Desktop.parcel b/Clario.Desktop/Clario.Desktop.parcel
new file mode 100644
index 0000000..ac44630
--- /dev/null
+++ b/Clario.Desktop/Clario.Desktop.parcel
@@ -0,0 +1,36 @@
+{
+ "GeneralSettings": {
+ "NetProjectPath": "Clario.Desktop.csproj",
+ "ApplicationName": "Clario",
+ "Version": "0.3.0",
+ "PackageName": {
+ "$type": "msbuild",
+ "property": "AssemblyName"
+ },
+ "AssemblyName": {
+ "$type": "msbuild",
+ "property": "AssemblyName"
+ }
+ },
+ "LinuxSettings": {
+ "AppIcon": "../Clario/Assets/Logo.png",
+ "CreateBinSymlink": "True"
+ },
+ "Win32Settings": {
+ "InstallerIcon": "../Clario/Assets/Clario-Logo.svg",
+ "Company": "Clario",
+ "IncludeUninstaller": "True"
+ },
+ "MacOsSettings": {
+ "CreateBundle": true,
+ "BundleIdentifier": "com.CompanyName.Clario-Desktop",
+ "SigningCredentialsType": "AdHoc"
+ },
+ "PublishSettings": {
+ "PublishSingleFile": "True",
+ "PublishReadyToRun": "True",
+ "ExtraBuildProperties": {
+ "RuntimeFrameworkVersion": "8.0.11"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Clario.iOS/Clario.iOS.csproj b/Clario.iOS/Clario.iOS.csproj
index f14564b..bf8b569 100644
--- a/Clario.iOS/Clario.iOS.csproj
+++ b/Clario.iOS/Clario.iOS.csproj
@@ -7,11 +7,14 @@
+
+
+
diff --git a/Clario/App.axaml b/Clario/App.axaml
index 223eabb..6a262f8 100644
--- a/Clario/App.axaml
+++ b/Clario/App.axaml
@@ -28,10 +28,13 @@
+
+
+
\ No newline at end of file
diff --git a/Clario/App.axaml.cs b/Clario/App.axaml.cs
index cfed3a8..b02f2ed 100644
--- a/Clario/App.axaml.cs
+++ b/Clario/App.axaml.cs
@@ -50,7 +50,7 @@ public partial class App : Application
}
IsMobile = ApplicationLifetime is ISingleViewApplicationLifetime;
-
+
var culture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentCulture = culture;
@@ -60,8 +60,9 @@ public partial class App : Application
{
await SupabaseService.Client.Auth.RetrieveSessionAsync();
}
- catch
+ catch (Exception e)
{
+ Console.WriteLine($"[Auth] RetrieveSession failed: {e.Message}");
}
var user = SupabaseService.Client.Auth.CurrentUser;
diff --git a/Clario/Assets/Icons/circle-check.svg b/Clario/Assets/Icons/circle-check.svg
new file mode 100644
index 0000000..05d65a4
--- /dev/null
+++ b/Clario/Assets/Icons/circle-check.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Clario/Assets/Icons/log-out.svg b/Clario/Assets/Icons/log-out.svg
new file mode 100644
index 0000000..9aaaa32
--- /dev/null
+++ b/Clario/Assets/Icons/log-out.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Clario/Assets/Icons/refresh-cw.svg b/Clario/Assets/Icons/refresh-cw.svg
new file mode 100644
index 0000000..b0edef9
--- /dev/null
+++ b/Clario/Assets/Icons/refresh-cw.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Clario/Assets/Icons/upload.svg b/Clario/Assets/Icons/upload.svg
new file mode 100644
index 0000000..9fc43a8
--- /dev/null
+++ b/Clario/Assets/Icons/upload.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Clario/Assets/Icons/wallet-cards.svg b/Clario/Assets/Icons/wallet-cards.svg
new file mode 100644
index 0000000..1682142
--- /dev/null
+++ b/Clario/Assets/Icons/wallet-cards.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Clario/Clario.csproj b/Clario/Clario.csproj
index c980a39..6d16347 100644
--- a/Clario/Clario.csproj
+++ b/Clario/Clario.csproj
@@ -13,6 +13,7 @@
+
@@ -30,6 +31,7 @@
+
@@ -38,5 +40,8 @@
MobileMainView.axaml
Code
+
+ AccountFormView.axaml
+
diff --git a/Clario/Converters/BoolToStringConverter.cs b/Clario/Converters/BoolToStringConverter.cs
new file mode 100644
index 0000000..7668f4d
--- /dev/null
+++ b/Clario/Converters/BoolToStringConverter.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Globalization;
+using Avalonia.Data.Converters;
+
+namespace Clario.Converters;
+
+public class BoolToStringConverter : IValueConverter
+{
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ if (value is not bool b || parameter is not string s) return null;
+ var results = s.Split('|');
+ return b ? results[0] : results[1];
+ }
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+}
\ No newline at end of file
diff --git a/Clario/Converters/CreditAmountConverter.cs b/Clario/Converters/CreditAmountConverter.cs
new file mode 100644
index 0000000..40ed11b
--- /dev/null
+++ b/Clario/Converters/CreditAmountConverter.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Globalization;
+using Avalonia.Data.Converters;
+
+namespace Clario.Converters;
+
+public class CreditAmountConverter : IValueConverter
+{
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ if (value is not decimal amount) return 0;
+ return amount < 0 ? amount * -1 : 0;
+ }
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+}
\ No newline at end of file
diff --git a/Clario/Converters/HexToColorConverter.cs b/Clario/Converters/HexToColorConverter.cs
index 259272f..2bba08c 100644
--- a/Clario/Converters/HexToColorConverter.cs
+++ b/Clario/Converters/HexToColorConverter.cs
@@ -1,5 +1,6 @@
using System;
using System.Globalization;
+using Avalonia.Controls.Converters;
using Avalonia.Data.Converters;
using Avalonia.Media;
@@ -21,6 +22,18 @@ public class HexToColorConverter : IValueConverter
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
- throw new NotImplementedException();
+ if (parameter is not string type) return null;
+ var color = Color.Parse("#ffffff");
+ if (value is Color c)
+ {
+ color = c;
+ }
+
+ if (value is SolidColorBrush b)
+ {
+ color = b.Color;
+ }
+
+ return $"#{color.R:X2}{color.G:X2}{color.B:X2}";
}
}
\ No newline at end of file
diff --git a/Clario/CustomControls/DateRangePicker.axaml b/Clario/CustomControls/DateRangePicker.axaml
index 160c99d..6d9d96a 100644
--- a/Clario/CustomControls/DateRangePicker.axaml
+++ b/Clario/CustomControls/DateRangePicker.axaml
@@ -2,6 +2,76 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Clario.CustomControls">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Clario/CustomControls/DateRangePicker.cs b/Clario/CustomControls/DateRangePicker.cs
index 90c1e13..84e5a53 100644
--- a/Clario/CustomControls/DateRangePicker.cs
+++ b/Clario/CustomControls/DateRangePicker.cs
@@ -5,8 +5,10 @@ using System.Linq;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
+using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;
+using Avalonia.VisualTree;
using Calendar = Avalonia.Controls.Calendar;
namespace Clario.CustomControls;
@@ -23,19 +25,28 @@ public class DateRangePicker : TemplatedControl
set => SetValue(SelectionModeProperty, value);
}
- public static readonly StyledProperty> SelectedDatesProperty =
- AvaloniaProperty.Register>(
- nameof(SelectedDates), new List());
+ // FIX: Use DirectProperty to avoid shared-instance default and get proper TwoWay support
+ private IList _selectedDates = new List();
+
+ public static readonly DirectProperty> SelectedDatesProperty =
+ AvaloniaProperty.RegisterDirect>(
+ nameof(SelectedDates),
+ o => o.SelectedDates,
+ (o, v) => o.SelectedDates = v,
+ defaultBindingMode: BindingMode.TwoWay);
public IList SelectedDates
{
- get => GetValue(SelectedDatesProperty);
- set => SetValue(SelectedDatesProperty, value);
+ get => _selectedDates;
+ set => SetAndRaise(SelectedDatesProperty, ref _selectedDates, value);
}
+ // FIX: Add defaultBindingMode: TwoWay so changes propagate back to the ViewModel
public static readonly StyledProperty SelectedDateProperty =
AvaloniaProperty.Register(
- nameof(SelectedDate), null);
+ nameof(SelectedDate),
+ defaultValue: null,
+ defaultBindingMode: BindingMode.TwoWay);
public DateTime? SelectedDate
{
@@ -58,7 +69,6 @@ public class DateRangePicker : TemplatedControl
private Popup? _popup;
private Calendar? _calendar;
-
private bool _isSyncing = false;
@@ -66,12 +76,12 @@ public class DateRangePicker : TemplatedControl
{
base.OnApplyTemplate(e);
-
if (_button != null) _button.Click -= OnButtonClick;
if (_calendar != null)
{
_calendar.SelectedDatesChanged -= OnCalendarDatesChanged;
_calendar.RemoveHandler(PointerReleasedEvent, OnCalendarPointerReleased);
+ // _calendar.RemoveHandler(Button.ClickEvent, OnCalendarInternalClick); // add this
}
_button = e.NameScope.Find