--- description: "Build the Blazor Hybrid UI shell, dashboard page, account detail page, entry table, dialogs, and responsive styling" agent: "agent" --- # Step 5: UI Shell & Pages Build all Blazor components in `src/Duempelkas.App/`. ## Page: Dashboard (`Pages/Dashboard.razor`) - Route: `/` - Displays all accounts as responsive Bootstrap cards using `AccountCardList` and `AccountCard` components. - Each card shows account name and formatted total balance (Euro). - A "Create Account" button opens `AddAccountDialog`. - Clicking a card navigates to `/accounts/{id}`. ## Page: Account Detail (`Pages/Accounts/AccountDetail.razor`) - Route: `/accounts/{AccountId:int}` - **Header area**: Account name, total balance (including carryover), year selector dropdown, "Add Year" button, "Export PDF" button. - **Main area**: Chronological entry table (oldest to newest) for the selected year. - "Add Entry" and "Add Transfer" buttons in a toolbar above the table. - Show yearly summary at the bottom: Opening balance, Year movement, Closing balance. ## Components (in `Components/Accounts/`) ### AccountCardList.razor - Renders a responsive grid of `AccountCard` components. ### AccountCard.razor / AccountCard.razor.css - Card displaying account name and total balance. - Click handler for navigation. ### AccountHeader.razor - Displays account name, total balance, year selector, action buttons. ### YearSelector.razor - Dropdown to select the active year, fires `EventCallback` on change. ### EntryTable.razor / EntryTable.razor.css - Table with columns: Date, Title, Type badge, Amount. - Rows sorted oldest → newest. - Transfer rows get a distinct visual indicator (e.g., link icon, blue highlight). ### EntryRow.razor - Single table row. Badge color: green for Income, red for Expense, blue for Transfer-linked. ### ExportButton.razor - Calls `IPdfStatementService` then `IFileSaveService` to save the PDF. ## Dialogs (in `Components/Dialogs/`) ### AddAccountDialog.razor - Modal with Name input. Calls `IAccountService.CreateAccountAsync`. ### AddYearDialog.razor - Modal with Year number input and Opening Balance input. Pre-fills suggested carryover. Calls `IAccountYearService.CreateYearAsync`. ### AddEntryDialog.razor - Modal with Type selector, Date, Title, Amount. Calls `IEntryService.CreateEntryAsync`. ### AddTransferDialog.razor - Modal with source/target account+year selectors, Date, Title, Amount. Calls `IEntryService.CreateTransferAsync`. ## Styling - Use Bootstrap 5 utilities for responsive layout. - Custom CSS in `wwwroot/css/app.css` for type badges, card hover states, and table row highlights. - Currency formatting: `amount.ToString("N2")` + " €" suffix. ## Conventions - Container/presentation split: pages load data, child components are presentational. - Use `@inject` for services. - Dialogs use a simple `bool IsVisible` pattern with backdrop overlay.