Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions decision/1-pagination-homepage-20251111-000000.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Solution Decision Document

## Problem Statement
Aggiungere la paginazione dei ristoranti nella home page (`Index.razor`), utilizzando una UX classica con controlli di paginazione e gestione della pagina corrente tramite query string nell’URL. Il backend supporta giΓ  la paginazione.

## Goal
Permettere agli utenti di navigare tra piΓΉ di 100 ristoranti tramite paginazione visibile e condivisibile via URL, mantenendo una UX familiare e ottimizzata per SEO.

## Selected Approach
Paginazione classica con controlli "Precedente/Successivo", gestione della pagina corrente tramite query string (`?page=2`), stile e dimensione pagina coerenti con la paginazione giΓ  presente in `RestaurantDetails.razor`.

## Alternatives Considered
- Option A: Infinite scroll β€” rejected because non richiesto, piΓΉ complesso, meno SEO-friendly.
- Option B: Paginazione lato client β€” rejected perchΓ© non scalabile con >100 ristoranti.
- Option C: Paginazione senza query string β€” rejected perchΓ© non permette deep linking e condivisione.
- Option D: Paginazione classica con query string β€” selezionata per coerenza, SEO, UX e supporto backend.

## Key Requirements

### Functional
- Visualizzazione paginata dei ristoranti.
- Controlli di navigazione pagina (precedente/successivo).
- Aggiornamento della lista in base alla pagina selezionata.
- Gestione della pagina corrente tramite query string.
- Deep linking e condivisione della pagina.

### Non-functional
- Performance: Caricamento solo dei ristoranti della pagina corrente.
- ScalabilitΓ : Supporto a >100 ristoranti.
- Security: Nessun dato sensibile esposto.
- Reliability: Gestione robusta di errori e pagine vuote.
- Observability: Log di errori e pagine non trovate.

## Constraints / Assumptions
- Il backend espone un metodo per ottenere ristoranti paginati.
- La UI puΓ² essere aggiornata per mostrare i controlli di paginazione.
- La dimensione pagina sarΓ  coerente con quella delle recensioni (es. 5 o 10).
- La query string viene gestita correttamente dal routing Blazor.

## Risks & Mitigations
- **Rischio:** Errori di sincronizzazione tra stato UI e URL.
- **Mitigazione:** Gestire OnParametersSetAsync per aggiornare la pagina corrente.
- **Rischio:** Navigazione su pagina non esistente.
- **Mitigazione:** Mostrare stato vuoto o tornare alla prima pagina.
- **Rischio:** Caricamento lento con molte pagine.
- **Mitigazione:** Limitare la dimensione pagina e ottimizzare query backend.

## Open Questions
- La dimensione pagina preferita Γ¨ 5, 10 o altro?
- Serve mostrare il numero totale di pagine/ristoranti?
- I controlli di paginazione devono essere visibili anche se c’è solo una pagina?
24 changes: 24 additions & 0 deletions specs/1/US-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# User Story

**Summary:** Paginate the homepage restaurant list

**As a** user
**I want** to see restaurants on the homepage paginated, with controls at the bottom
**So that** I can easily browse large numbers of restaurants

## Requirements
- Display restaurants on the homepage in pages of 3 items each
- Pagination controls are always shown at the bottom of the list
- Accessibility: controls must support keyboard navigation and ARIA labels
- Show a loading indicator when switching pages
- If a page fails to load, throw an error
- If there are zero restaurants or only one page, do not show pagination buttons

## Non-functional considerations
- Accessibility: keyboard navigation, ARIA labels
- Performance: loading indicator for page transitions
- UX: clear error handling, no unnecessary controls

## Notes
- Source: Solution Decision Document + approved clarifications
- These requirements are locked and not subject to change here
1 change: 1 addition & 0 deletions src/DevEats.Core/Interfaces/IRestaurantService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public interface IRestaurantService
{
Task<Restaurant?> GetByIdAsync(int id);
Task<IEnumerable<Restaurant>> GetAllAsync();
Task<PagedResult<Restaurant>> GetRestaurantsPagedAsync(int pageNumber, int pageSize);
Task<Restaurant> AddAsync(Restaurant restaurant);
Task UpdateAsync(Restaurant restaurant);
Task DeleteAsync(int id);
Expand Down
26 changes: 26 additions & 0 deletions src/DevEats.Infrastructure/Services/RestaurantService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,32 @@ public async Task<IEnumerable<Restaurant>> GetAllAsync()
.ToListAsync();
}

public async Task<PagedResult<Restaurant>> GetRestaurantsPagedAsync(int pageNumber, int pageSize)
{
if (pageNumber < 1) pageNumber = 1;
if (pageSize < 1) pageSize = 1;

var query = _context.Restaurants
.Include(r => r.Reviews)
.OrderByDescending(r => r.AverageRating);

var totalCount = await query.CountAsync();

var items = await query
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToListAsync();

_logger.LogInformation("Fetched {RestaurantCount} restaurants for page {PageNumber}", items.Count, pageNumber);
return new PagedResult<Restaurant>
{
Items = items,
TotalCount = totalCount,
PageNumber = pageNumber,
PageSize = pageSize
};
}

public async Task<Restaurant> AddAsync(Restaurant restaurant)
{
_context.Restaurants.Add(restaurant);
Expand Down
Loading
Loading