diff --git a/Marechai.App/Presentation/ComputersListPage.xaml b/Marechai.App/Presentation/ComputersListPage.xaml
new file mode 100644
index 00000000..d07b048b
--- /dev/null
+++ b/Marechai.App/Presentation/ComputersListPage.xaml
@@ -0,0 +1,261 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Marechai.App/Presentation/ComputersListPage.xaml.cs b/Marechai.App/Presentation/ComputersListPage.xaml.cs
new file mode 100644
index 00000000..4b907dea
--- /dev/null
+++ b/Marechai.App/Presentation/ComputersListPage.xaml.cs
@@ -0,0 +1,36 @@
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Controls;
+
+namespace Marechai.App.Presentation;
+
+///
+/// Professional list view for displaying computers filtered by letter, year, or all.
+/// Features responsive layout, modern styling, and smooth navigation.
+///
+public sealed partial class ComputersListPage : Page
+{
+ public ComputersListPage()
+ {
+ InitializeComponent();
+ Loaded += ComputersListPage_Loaded;
+ DataContextChanged += ComputersListPage_DataContextChanged;
+ }
+
+ private void ComputersListPage_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
+ {
+ if(DataContext is ComputersListViewModel vm)
+ {
+ // Load data when DataContext is set
+ vm.LoadData.Execute(null);
+ }
+ }
+
+ private void ComputersListPage_Loaded(object sender, RoutedEventArgs e)
+ {
+ if(DataContext is ComputersListViewModel vm)
+ {
+ // Load data when page is loaded (fallback)
+ vm.LoadData.Execute(null);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Marechai.App/Presentation/ComputersListViewModel.cs b/Marechai.App/Presentation/ComputersListViewModel.cs
new file mode 100644
index 00000000..dd9dfdaa
--- /dev/null
+++ b/Marechai.App/Presentation/ComputersListViewModel.cs
@@ -0,0 +1,249 @@
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Input;
+using Marechai.App.Services;
+using Uno.Extensions.Navigation;
+
+namespace Marechai.App.Presentation;
+
+///
+/// ViewModel for displaying a filtered list of computers
+///
+public partial class ComputersListViewModel : ObservableObject
+{
+ private readonly ComputersService _computersService;
+ private readonly IComputersListFilterContext _filterContext;
+ private readonly IStringLocalizer _localizer;
+ private readonly ILogger _logger;
+ private readonly INavigator _navigator;
+
+ [ObservableProperty]
+ private ObservableCollection computersList = [];
+
+ [ObservableProperty]
+ private string errorMessage = string.Empty;
+
+ [ObservableProperty]
+ private string filterDescription = string.Empty;
+
+ [ObservableProperty]
+ private bool hasError;
+
+ [ObservableProperty]
+ private bool isDataLoaded;
+
+ [ObservableProperty]
+ private bool isLoading;
+
+ [ObservableProperty]
+ private string pageTitle = string.Empty;
+
+ public ComputersListViewModel(ComputersService computersService, IStringLocalizer localizer,
+ ILogger logger, INavigator navigator,
+ IComputersListFilterContext filterContext)
+ {
+ _computersService = computersService;
+ _localizer = localizer;
+ _logger = logger;
+ _navigator = navigator;
+ _filterContext = filterContext;
+ LoadData = new AsyncRelayCommand(LoadDataAsync);
+ GoBackCommand = new AsyncRelayCommand(GoBackAsync);
+ NavigateToComputerCommand = new AsyncRelayCommand(NavigateToComputerAsync);
+ }
+
+ public IAsyncRelayCommand LoadData { get; }
+ public ICommand GoBackCommand { get; }
+ public IAsyncRelayCommand NavigateToComputerCommand { get; }
+
+ ///
+ /// Gets or sets the filter type
+ ///
+ public ComputerListFilterType FilterType
+ {
+ get => _filterContext.FilterType;
+ set => _filterContext.FilterType = value;
+ }
+
+ ///
+ /// Gets or sets the filter value
+ ///
+ public string FilterValue
+ {
+ get => _filterContext.FilterValue;
+ set => _filterContext.FilterValue = value;
+ }
+
+ ///
+ /// Loads computers based on the current filter
+ ///
+ private async Task LoadDataAsync()
+ {
+ try
+ {
+ IsLoading = true;
+ ErrorMessage = string.Empty;
+ HasError = false;
+ IsDataLoaded = false;
+ ComputersList.Clear();
+
+ _logger.LogInformation("LoadDataAsync called. FilterType={FilterType}, FilterValue={FilterValue}",
+ FilterType,
+ FilterValue);
+
+ // Update title and filter description based on filter type
+ UpdateFilterDescription();
+
+ // Load computers from the API based on the current filter
+ await LoadComputersFromApiAsync();
+
+ _logger.LogInformation("LoadComputersFromApiAsync completed. ComputersList.Count={Count}",
+ ComputersList.Count);
+
+ if(ComputersList.Count == 0)
+ {
+ ErrorMessage = _localizer["No computers found for this filter"].Value;
+ HasError = true;
+
+ _logger.LogWarning("No computers found for filter: {FilterType} {FilterValue}",
+ FilterType,
+ FilterValue);
+ }
+ else
+ IsDataLoaded = true;
+ }
+ catch(Exception ex)
+ {
+ _logger.LogError(ex, "Error loading computers: {Exception}", ex.Message);
+ ErrorMessage = _localizer["Failed to load computers. Please try again later."].Value;
+ HasError = true;
+ }
+ finally
+ {
+ IsLoading = false;
+ }
+ }
+
+ ///
+ /// Updates the title and filter description based on the current filter
+ ///
+ private void UpdateFilterDescription()
+ {
+ switch(FilterType)
+ {
+ case ComputerListFilterType.All:
+ PageTitle = _localizer["All Computers"];
+ FilterDescription = _localizer["Browsing all computers in the database"];
+
+ break;
+
+ case ComputerListFilterType.Letter:
+ if(!string.IsNullOrEmpty(FilterValue) && FilterValue.Length == 1)
+ {
+ PageTitle = $"{_localizer["Computers Starting with"]} {FilterValue}";
+ FilterDescription = $"{_localizer["Showing computers that start with"]} {FilterValue}";
+ }
+
+ break;
+
+ case ComputerListFilterType.Year:
+ if(!string.IsNullOrEmpty(FilterValue) && int.TryParse(FilterValue, out int year))
+ {
+ PageTitle = $"{_localizer["Computers from"]} {year}";
+ FilterDescription = $"{_localizer["Showing computers released in"]} {year}";
+ }
+
+ break;
+ }
+ }
+
+ ///
+ /// Loads computers from the API based on the current filter
+ ///
+ private async Task LoadComputersFromApiAsync()
+ {
+ try
+ {
+ List computers = FilterType switch
+ {
+ ComputerListFilterType.Letter when FilterValue.Length == 1 =>
+ await _computersService.GetComputersByLetterAsync(FilterValue[0]),
+
+ ComputerListFilterType.Year when int.TryParse(FilterValue, out int year) =>
+ await _computersService.GetComputersByYearAsync(year),
+
+ _ => await _computersService.GetAllComputersAsync()
+ };
+
+ // Add computers to the list sorted by name
+ foreach(MachineDto computer in computers.OrderBy(c => c.Name))
+ {
+ int year = computer.Introduced?.Year ?? 0;
+ int id = UntypedNodeExtractor.ExtractInt(computer.Id);
+
+ _logger.LogInformation("Computer: {Name}, Introduced: {Introduced}, Year: {Year}, Company: {Company}, ID: {Id}",
+ computer.Name,
+ computer.Introduced,
+ year,
+ computer.Company,
+ id);
+
+ ComputersList.Add(new ComputerListItem
+ {
+ Id = id,
+ Name = computer.Name ?? string.Empty,
+ Year = year,
+ Manufacturer = computer.Company ?? string.Empty
+ });
+ }
+ }
+ catch(Exception ex)
+ {
+ _logger.LogError(ex, "Error loading computers from API");
+ }
+ }
+
+ ///
+ /// Navigates back to the computers main view
+ ///
+ private async Task GoBackAsync()
+ {
+ await _navigator.NavigateViewModelAsync(this);
+ }
+
+ ///
+ /// Navigates to the computer detail view
+ ///
+ private async Task NavigateToComputerAsync(ComputerListItem? computer)
+ {
+ if(computer is null) return;
+
+ _logger.LogInformation("Navigating to computer detail: {ComputerName} (ID: {ComputerId})",
+ computer.Name,
+ computer.Id);
+
+ var navParam = new MachineViewNavigationParameter
+ {
+ MachineId = computer.Id,
+ NavigationSource = this
+ };
+
+ await _navigator.NavigateViewModelAsync(this, data: navParam);
+ }
+}
+
+///
+/// Data model for a computer in the list
+///
+public class ComputerListItem
+{
+ public int Id { get; set; }
+ public string Name { get; set; } = string.Empty;
+ public int Year { get; set; }
+ public string Manufacturer { get; set; } = string.Empty;
+}
\ No newline at end of file