diff --git a/Amaltea/Amaltea.csproj b/Amaltea/Amaltea.csproj
new file mode 100644
index 0000000..e3e33e3
--- /dev/null
+++ b/Amaltea/Amaltea.csproj
@@ -0,0 +1,11 @@
+
+
+
+ WinExe
+ net8.0-windows
+ enable
+ enable
+ true
+
+
+
diff --git a/Amaltea/Amaltea.sln b/Amaltea/Amaltea.sln
new file mode 100644
index 0000000..ab457b9
--- /dev/null
+++ b/Amaltea/Amaltea.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.14.36429.23 d17.14
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amaltea", "Amaltea.csproj", "{11514D9A-D918-4E19-84CA-0D72FFA124B1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {11514D9A-D918-4E19-84CA-0D72FFA124B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {11514D9A-D918-4E19-84CA-0D72FFA124B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {11514D9A-D918-4E19-84CA-0D72FFA124B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {11514D9A-D918-4E19-84CA-0D72FFA124B1}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {02F963B3-CBB5-49DB-9A2B-3182AE54069A}
+ EndGlobalSection
+EndGlobal
diff --git a/Amaltea/Amaltea/Converters/BlockTypeToBrushConverter.cs b/Amaltea/Amaltea/Converters/BlockTypeToBrushConverter.cs
new file mode 100644
index 0000000..35df635
--- /dev/null
+++ b/Amaltea/Amaltea/Converters/BlockTypeToBrushConverter.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using System.Windows.Media;
+using Amaltea.ViewModels;
+
+namespace Amaltea.Converters;
+
+public class BlockTypeToBrushConverter : IValueConverter
+{
+ public object? Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is StrategyBlockType type)
+ {
+ var resourceKey = type switch
+ {
+ StrategyBlockType.Trigger => "Brush.Block.Trigger",
+ StrategyBlockType.Condition => "Brush.Block.Condition",
+ StrategyBlockType.Action => "Brush.Block.Action",
+ StrategyBlockType.Risk => "Brush.Block.Risk",
+ _ => "Brush.Block.Trigger"
+ };
+ return App.Current.TryFindResource(resourceKey) as Brush;
+ }
+ return null;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
+}
diff --git a/Amaltea/Amaltea/Converters/NullToVisibilityConverter.cs b/Amaltea/Amaltea/Converters/NullToVisibilityConverter.cs
new file mode 100644
index 0000000..2ba4e81
--- /dev/null
+++ b/Amaltea/Amaltea/Converters/NullToVisibilityConverter.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace Amaltea.Converters;
+
+public class NullToVisibilityConverter : IValueConverter
+{
+ // If parameter == "Invert" then returns Visible when value is null.
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ bool invert = string.Equals(parameter as string, "Invert", StringComparison.OrdinalIgnoreCase);
+ bool isNull = value is null;
+ if (invert)
+ return isNull ? Visibility.Visible : Visibility.Collapsed;
+ return isNull ? Visibility.Collapsed : Visibility.Visible;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
+}
diff --git a/Amaltea/Amaltea/ViewModels/BaseViewModel.cs b/Amaltea/Amaltea/ViewModels/BaseViewModel.cs
new file mode 100644
index 0000000..2f088e3
--- /dev/null
+++ b/Amaltea/Amaltea/ViewModels/BaseViewModel.cs
@@ -0,0 +1,20 @@
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+
+namespace Amaltea.ViewModels;
+
+public abstract class BaseViewModel : INotifyPropertyChanged
+{
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ protected void RaisePropertyChanged([CallerMemberName] string? propertyName = null)
+ => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+
+ protected bool SetProperty(ref T storage, T value, [CallerMemberName] string? propertyName = null)
+ {
+ if (Equals(storage, value)) return false;
+ storage = value;
+ RaisePropertyChanged(propertyName);
+ return true;
+ }
+}
diff --git a/Amaltea/Amaltea/ViewModels/StrategyBlockViewModel.cs b/Amaltea/Amaltea/ViewModels/StrategyBlockViewModel.cs
new file mode 100644
index 0000000..ec6dc23
--- /dev/null
+++ b/Amaltea/Amaltea/ViewModels/StrategyBlockViewModel.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Windows;
+using System.Windows.Media;
+
+namespace Amaltea.ViewModels;
+
+public enum StrategyBlockType
+{
+ Trigger,
+ Condition,
+ Action,
+ Risk
+}
+
+public class StrategyBlockViewModel : BaseViewModel
+{
+ private double _x;
+ private double _y;
+ private string _title = string.Empty;
+ private string? _subtitle;
+ private StrategyBlockType _blockType;
+ private bool _isSelected;
+
+ public Guid Id { get; } = Guid.NewGuid();
+
+ public double X { get => _x; set => SetProperty(ref _x, value); }
+ public double Y { get => _y; set => SetProperty(ref _y, value); }
+
+ public string Title { get => _title; set => SetProperty(ref _title, value); }
+ public string? Subtitle { get => _subtitle; set => SetProperty(ref _subtitle, value); }
+
+ public StrategyBlockType BlockType { get => _blockType; set { if (SetProperty(ref _blockType, value)) RaisePropertyChanged(nameof(BlockBrushKey)); } }
+
+ public bool IsSelected { get => _isSelected; set => SetProperty(ref _isSelected, value); }
+
+ public string BlockBrushKey => BlockType switch
+ {
+ StrategyBlockType.Trigger => "Brush.Block.Trigger",
+ StrategyBlockType.Condition => "Brush.Block.Condition",
+ StrategyBlockType.Action => "Brush.Block.Action",
+ StrategyBlockType.Risk => "Brush.Block.Risk",
+ _ => "Brush.Block.Trigger"
+ };
+}
diff --git a/Amaltea/Amaltea/ViewModels/StrategyEditorViewModel.cs b/Amaltea/Amaltea/ViewModels/StrategyEditorViewModel.cs
new file mode 100644
index 0000000..8270ecc
--- /dev/null
+++ b/Amaltea/Amaltea/ViewModels/StrategyEditorViewModel.cs
@@ -0,0 +1,151 @@
+using System.Collections.ObjectModel;
+using System.Text.Json;
+using System.IO;
+using System.Linq;
+using System.Collections.Generic;
+
+namespace Amaltea.ViewModels;
+
+public class StrategyEditorViewModel : BaseViewModel
+{
+ private StrategyBlockViewModel? _selectedBlock;
+ private readonly ObservableCollection _selectedBlocks = new();
+
+ public ObservableCollection Blocks { get; } = new();
+ public ObservableCollection Connections { get; } = new();
+
+ public IEnumerable SelectedBlocks => _selectedBlocks;
+
+ public StrategyBlockViewModel? SelectedBlock
+ {
+ get => _selectedBlock;
+ set
+ {
+ if (SetProperty(ref _selectedBlock, value))
+ {
+ _selectedBlocks.Clear();
+ if (value != null)
+ {
+ value.IsSelected = true;
+ _selectedBlocks.Add(value);
+ }
+ RaisePropertyChanged(nameof(SelectedBlocks));
+ }
+ }
+ }
+
+ public StrategyEditorViewModel()
+ {
+ // Seed with demo blocks
+ var b1 = new StrategyBlockViewModel { Title = "Event Trigger", Subtitle = "In-Play Start", X = 60, Y = 60, BlockType = StrategyBlockType.Trigger };
+ var b2 = new StrategyBlockViewModel { Title = "Condition: Odds", Subtitle = "Back Odds < 3.0", X = 260, Y = 160, BlockType = StrategyBlockType.Condition };
+ var b3 = new StrategyBlockViewModel { Title = "Action: Back", Subtitle = "Stake 10 EUR", X = 520, Y = 180, BlockType = StrategyBlockType.Action };
+ var b4 = new StrategyBlockViewModel { Title = "Risk Mgmt", Subtitle = "Stop Loss 5%", X = 760, Y = 260, BlockType = StrategyBlockType.Risk };
+
+ Blocks.Add(b1);
+ Blocks.Add(b2);
+ Blocks.Add(b3);
+ Blocks.Add(b4);
+
+ Connections.Add(new StrategyConnectionViewModel(b1.Id, b2.Id));
+ Connections.Add(new StrategyConnectionViewModel(b2.Id, b3.Id));
+ Connections.Add(new StrategyConnectionViewModel(b3.Id, b4.Id));
+ }
+
+ public StrategyBlockViewModel AddBlock(StrategyBlockType type, string title, string subtitle, double x, double y)
+ {
+ var block = new StrategyBlockViewModel { BlockType = type, Title = title, Subtitle = subtitle, X = x, Y = y };
+ Blocks.Add(block);
+ return block;
+ }
+
+ public void AddConnection(StrategyBlockViewModel from, StrategyBlockViewModel to)
+ {
+ if (from == to) return;
+ if (Connections.Any(c => c.From == from.Id && c.To == to.Id)) return;
+ Connections.Add(new StrategyConnectionViewModel(from.Id, to.Id));
+ }
+
+ public void ClearSelection()
+ {
+ foreach (var b in _selectedBlocks) b.IsSelected = false;
+ _selectedBlocks.Clear();
+ _selectedBlock = null;
+ RaisePropertyChanged(nameof(SelectedBlocks));
+ RaisePropertyChanged(nameof(SelectedBlock));
+ }
+
+ public void ToggleSelection(StrategyBlockViewModel block, bool add)
+ {
+ if (!add)
+ {
+ ClearSelection();
+ block.IsSelected = true;
+ _selectedBlocks.Add(block);
+ _selectedBlock = block;
+ }
+ else
+ {
+ if (_selectedBlocks.Contains(block))
+ {
+ block.IsSelected = false;
+ _selectedBlocks.Remove(block);
+ }
+ else
+ {
+ block.IsSelected = true;
+ _selectedBlocks.Add(block);
+ }
+ _selectedBlock = _selectedBlocks.LastOrDefault();
+ }
+ RaisePropertyChanged(nameof(SelectedBlocks));
+ RaisePropertyChanged(nameof(SelectedBlock));
+ }
+
+ public string Serialize()
+ {
+ var dto = new StrategyGraphDto
+ {
+ Blocks = Blocks.Select(b => new StrategyBlockDto
+ {
+ Id = b.Id,
+ X = b.X,
+ Y = b.Y,
+ Title = b.Title,
+ Subtitle = b.Subtitle,
+ BlockType = b.BlockType
+ }).ToList(),
+ Connections = Connections.Select(c => new StrategyConnectionDto { From = c.From, To = c.To }).ToList()
+ };
+ return JsonSerializer.Serialize(dto, new JsonSerializerOptions { WriteIndented = true });
+ }
+
+ public void SaveToFile(string path)
+ {
+ File.WriteAllText(path, Serialize());
+ }
+}
+
+public record StrategyConnectionViewModel(System.Guid From, System.Guid To);
+
+public class StrategyGraphDto
+{
+ public List Blocks { get; set; } = new();
+ public List Connections { get; set; } = new();
+}
+
+public class StrategyBlockDto
+{
+ public System.Guid Id { get; set; }
+ public double X { get; set; }
+ public double Y { get; set; }
+ public string? Title { get; set; }
+ public string? Subtitle { get; set; }
+ public StrategyBlockType BlockType { get; set; }
+}
+
+public class StrategyConnectionDto
+{
+ public System.Guid From { get; set; }
+ public System.Guid To { get; set; }
+}
diff --git a/Amaltea/Amaltea/Views/StrategyEditorView.xaml b/Amaltea/Amaltea/Views/StrategyEditorView.xaml
new file mode 100644
index 0000000..2354902
--- /dev/null
+++ b/Amaltea/Amaltea/Views/StrategyEditorView.xaml
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Amaltea/Amaltea/Views/StrategyEditorView.xaml.cs b/Amaltea/Amaltea/Views/StrategyEditorView.xaml.cs
new file mode 100644
index 0000000..39b59e0
--- /dev/null
+++ b/Amaltea/Amaltea/Views/StrategyEditorView.xaml.cs
@@ -0,0 +1,95 @@
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using Amaltea.ViewModels;
+using Microsoft.Win32;
+
+namespace Amaltea.Views
+{
+ public partial class StrategyEditorView : UserControl
+ {
+ private StrategyEditorViewModel Vm => (StrategyEditorViewModel)DataContext;
+ private bool _dragging;
+ private StrategyBlockViewModel? _dragBlock;
+ private Point _dragStartPos;
+ private Point _blockStartPos;
+ private StrategyBlockViewModel? _pendingConnectionFrom;
+
+ public StrategyEditorView()
+ {
+ InitializeComponent();
+ DataContext = new StrategyEditorViewModel();
+ }
+
+ private void AddTrigger_Click(object sender, RoutedEventArgs e) => Vm.AddBlock(StrategyBlockType.Trigger, "Event Trigger", "Custom", 80, 80);
+ private void AddCondition_Click(object sender, RoutedEventArgs e) => Vm.AddBlock(StrategyBlockType.Condition, "Condition", "Edit...", 120, 120);
+ private void AddAction_Click(object sender, RoutedEventArgs e) => Vm.AddBlock(StrategyBlockType.Action, "Action", "Edit...", 160, 160);
+ private void AddRisk_Click(object sender, RoutedEventArgs e) => Vm.AddBlock(StrategyBlockType.Risk, "Risk", "Edit...", 200, 200);
+
+ private void Block_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+ {
+ if (sender is not Border border || border.DataContext is not StrategyBlockViewModel block) return;
+
+ bool ctrl = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);
+
+ if (_pendingConnectionFrom != null && _pendingConnectionFrom != block && ctrl)
+ {
+ Vm.AddConnection(_pendingConnectionFrom, block);
+ _pendingConnectionFrom = null;
+ }
+ else if (ctrl)
+ {
+ _pendingConnectionFrom = block;
+ }
+
+ Vm.ToggleSelection(block, ctrl);
+
+ _dragging = true;
+ _dragBlock = block;
+ _dragStartPos = e.GetPosition(WorkspaceCanvas);
+ _blockStartPos = new Point(block.X, block.Y);
+ border.CaptureMouse();
+ }
+
+ private void Block_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (!_dragging || _dragBlock == null) return;
+ var current = e.GetPosition(WorkspaceCanvas);
+ var delta = current - _dragStartPos;
+ _dragBlock.X = _blockStartPos.X + delta.X;
+ _dragBlock.Y = _blockStartPos.Y + delta.Y;
+ }
+
+ private void Block_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+ {
+ if (sender is not Border border) return;
+ _dragging = false;
+ _dragBlock = null;
+ border.ReleaseMouseCapture();
+ }
+
+ private void WorkspaceCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+ {
+ if (e.Source == WorkspaceCanvas)
+ {
+ Vm.ClearSelection();
+ _pendingConnectionFrom = null;
+ }
+ }
+
+ private void SaveStrategy_Click(object sender, RoutedEventArgs e)
+ {
+ var dialog = new SaveFileDialog
+ {
+ Filter = "Strategy JSON (*.json)|*.json",
+ FileName = "strategy.json"
+ };
+ if (dialog.ShowDialog() == true)
+ {
+ Vm.SaveToFile(dialog.FileName);
+ }
+ }
+ }
+}
diff --git a/Amaltea/App.xaml b/Amaltea/App.xaml
new file mode 100644
index 0000000..2c3a418
--- /dev/null
+++ b/Amaltea/App.xaml
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+ #1E1F23
+ #24262B
+ #2C2F33
+ #3A3D43
+ #2E8CFF
+ #4FA2FF
+ #FFFFFF
+ #B0B4BA
+ #2ECC71
+ #E5C457
+ #E55252
+
+ #2475D8
+ #8E44AD
+ #2ECC71
+ #E67E22
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Amaltea/App.xaml.cs b/Amaltea/App.xaml.cs
new file mode 100644
index 0000000..0748ad4
--- /dev/null
+++ b/Amaltea/App.xaml.cs
@@ -0,0 +1,14 @@
+using System.Configuration;
+using System.Data;
+using System.Windows;
+
+namespace Amaltea
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ }
+
+}
diff --git a/Amaltea/AssemblyInfo.cs b/Amaltea/AssemblyInfo.cs
new file mode 100644
index 0000000..b0ec827
--- /dev/null
+++ b/Amaltea/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/Amaltea/MainWindow.xaml b/Amaltea/MainWindow.xaml
new file mode 100644
index 0000000..d4759e6
--- /dev/null
+++ b/Amaltea/MainWindow.xaml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Amaltea/MainWindow.xaml.cs b/Amaltea/MainWindow.xaml.cs
new file mode 100644
index 0000000..9d6ab5b
--- /dev/null
+++ b/Amaltea/MainWindow.xaml.cs
@@ -0,0 +1,156 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using Amaltea.Views;
+
+namespace Amaltea
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ private enum ConnectionState
+ {
+ Disconnected,
+ Connecting,
+ Connected,
+ Failed
+ }
+
+ private ConnectionState _connectionState = ConnectionState.Disconnected;
+ private CancellationTokenSource? _connectionCts;
+ private readonly Random _random = new();
+
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+
+ private async void ConnectButton_Click(object sender, RoutedEventArgs e)
+ {
+ if (_connectionState == ConnectionState.Connected)
+ {
+ SetConnectionState(ConnectionState.Disconnected, "Disconnected");
+ return;
+ }
+
+ await ConnectToBetfairAsync();
+ }
+
+ private void SetConnectionState(ConnectionState state, string? overrideText = null)
+ {
+ _connectionState = state;
+ switch (state)
+ {
+ case ConnectionState.Disconnected:
+ ConnectButton.Content = "Connect";
+ ConnectionStatusTextBlock.Text = overrideText ?? "Disconnected";
+ GlobalStatusTextBlock.Text = "Ready";
+ break;
+ case ConnectionState.Connecting:
+ ConnectButton.Content = "Cancel";
+ ConnectionStatusTextBlock.Text = overrideText ?? "Connecting...";
+ GlobalStatusTextBlock.Text = "Connecting to Betfair...";
+ break;
+ case ConnectionState.Connected:
+ ConnectButton.Content = "Disconnect";
+ ConnectionStatusTextBlock.Text = overrideText ?? "Connected";
+ GlobalStatusTextBlock.Text = "Connected to Betfair";
+ break;
+ case ConnectionState.Failed:
+ ConnectButton.Content = "Retry";
+ ConnectionStatusTextBlock.Text = overrideText ?? "Connection Failed";
+ GlobalStatusTextBlock.Text = "Connection failed";
+ break;
+ }
+ }
+
+ ///
+ /// Simulates an async connection to the Betfair API.
+ /// Later this will be replaced with real authentication / session logic.
+ ///
+ private async Task ConnectToBetfairAsync()
+ {
+ // If already connecting allow cancel.
+ if (_connectionState == ConnectionState.Connecting)
+ {
+ _connectionCts?.Cancel();
+ return;
+ }
+
+ _connectionCts = new CancellationTokenSource();
+ var token = _connectionCts.Token;
+
+ try
+ {
+ SetConnectionState(ConnectionState.Connecting);
+
+ // Simulate variable latency 3-5 seconds.
+ var delay = TimeSpan.FromSeconds(_random.Next(3, 6));
+ await Task.Delay(delay, token);
+
+ token.ThrowIfCancellationRequested();
+
+ // Randomly simulate success or failure (80% success for now)
+ var success = _random.NextDouble() < 0.8;
+ if (success)
+ {
+ SetConnectionState(ConnectionState.Connected);
+ }
+ else
+ {
+ SetConnectionState(ConnectionState.Failed);
+ }
+ }
+ catch (OperationCanceledException)
+ {
+ SetConnectionState(ConnectionState.Disconnected, "Canceled");
+ }
+ catch (Exception ex)
+ {
+ SetConnectionState(ConnectionState.Failed, ex.Message);
+ }
+ }
+
+ private void NavButton_Click(object sender, RoutedEventArgs e)
+ {
+ if (sender is not Button btn) return;
+ var tag = btn.Tag?.ToString() ?? string.Empty;
+ HeaderTitleTextBlock.Text = tag switch
+ {
+ "Dashboard" => "Dashboard",
+ "StrategyEditor" => "Strategy Editor",
+ "Backtesting" => "Backtesting",
+ "Account" => "Account",
+ "Settings" => "Settings",
+ _ => "Dashboard"
+ };
+
+ // Replace main content based on tag (placeholder for now)
+ MainContentArea.Children.Clear();
+
+ if (tag == "StrategyEditor")
+ {
+ MainContentArea.Children.Add(new StrategyEditorView());
+ return;
+ }
+
+ MainContentArea.Children.Add(new TextBlock
+ {
+ Text = $"Sezione: {HeaderTitleTextBlock.Text}",
+ FontSize = 22,
+ FontWeight = FontWeights.Bold,
+ Margin = new Thickness(0,0,0,12)
+ });
+ MainContentArea.Children.Add(new TextBlock
+ {
+ Text = "Contenuto placeholder. Qui verrà caricata l'interfaccia specifica della sezione.",
+ TextWrapping = TextWrapping.Wrap,
+ Foreground = (System.Windows.Media.Brush)FindResource("Brush.TextSecondary")
+ });
+ }
+ }
+}
\ No newline at end of file