Request Status
Documentație pentru componentele FodRequestStatus și FodRequestStatusResponse
1. Descriere Generală
FodRequestStatus
și FodRequestStatusResponse
sunt componente business specializate pentru sistemul FOD (Furnizor de date și servicii publice) din Moldova. Acestea permit utilizatorilor să verifice statusul cererilor depuse la instituțiile publice.
Componente: - FodRequestStatus - Formularul principal de căutare a statusului - FodRequestStatusResponse - Afișarea rezultatelor căutării cu detalii complete
Caracteristici principale: - Căutare după cuvânt cheie (număr cerere, cod serviciu) - Afișare rezultate paginată - Panouri expandabile pentru fiecare cerere - Informații despre livrare și ridicare - Status apostilare pentru documente - Suport pentru localizare (română/rusă) - Validare formular integrată
2. Arhitectură și dependințe
// Servicii necesare
services.AddScoped<IRequestStatusService, RequestStatusService>();
// Modele utilizate
public class RequestStatusRequestModel
{
[Required]
public string Keyword { get; set; }
}
public class RequestStatusResponseModel
{
public string OrderNumber { get; set; }
public string ServiceProviderNumber { get; set; }
public string Status { get; set; }
public List<string> Services { get; set; }
public string ReceptionMode { get; set; }
public bool RequiresResponseOnPaper { get; set; }
public bool RequiresDelivery { get; set; }
public PickupLocationModel PickupLocation { get; set; }
public DeliveryModel Delivery { get; set; }
public DateTime SubmissionDate { get; set; }
public DateTime? EstimatedResolveDate { get; set; }
public bool RequiresApostilation { get; set; }
public List<ApostilaDetailsModel> ApostilaDetails { get; set; }
public string FodResponsibleDivision { get; set; }
}
3. Ghid de Utilizare API
Implementare simplă
@page "/verifica-status"
<FodRequestStatus />
Implementare cu handler personalizat
<FodRequestStatus OnSearchCompleted="HandleSearchResults" />
@code {
private void HandleSearchResults(List<RequestStatusResponseModel> results)
{
Console.WriteLine($"S-au găsit {results.Count} cereri");
// Procesare rezultate
}
}
Implementare cu pre-populare
<FodRequestStatus InitialKeyword="@orderNumber" AutoSearch="true" />
@code {
[Parameter]
[SupplyParameterFromQuery]
public string orderNumber { get; set; }
}
4. Atribute disponibile
FodRequestStatus
Proprietate | Tip | Descriere | Valoare Implicită |
---|---|---|---|
InitialKeyword |
string |
Cuvânt cheie pre-populat | null |
AutoSearch |
bool |
Pornește căutarea automat | false |
OnSearchStarted |
EventCallback |
Eveniment început căutare | - |
OnSearchCompleted |
EventCallback<List<RequestStatusResponseModel>> |
Eveniment finalizare căutare | - |
ShowAlert |
bool |
Afișează alerta informativă | true |
CustomAlertText |
string |
Text personalizat pentru alertă | - |
FodRequestStatusResponse
Proprietate | Tip | Descriere | Valoare Implicită |
---|---|---|---|
Model |
List<RequestStatusResponseModel> |
Lista rezultatelor | - |
Keyword |
string |
Cuvântul cheie căutat | - |
PageSize |
int |
Număr rezultate per pagină | 10 |
ShowPagination |
bool |
Afișează paginarea | true |
5. Exemple de utilizare
Pagină completă de verificare status
@page "/verifica-cerere"
@using FOD.Components.Resources
@inject IStringLocalizer<General> L
<FodContainer MaxWidth="MaxWidth.Medium">
<FodText Typo="Typo.h3" GutterBottom="true">
@L["Check_Request_Status"]
</FodText>
<FodPaper Class="pa-4 mt-4">
<FodRequestStatus
ShowAlert="true"
OnSearchCompleted="@OnSearchCompleted" />
</FodPaper>
@if (hasResults)
{
<FodAlert Severity="Severity.Success" Class="mt-3">
<FodAlertTitle>Rezultate găsite</FodAlertTitle>
S-au găsit @resultCount cereri pentru căutarea dvs.
</FodAlert>
}
</FodContainer>
@code {
private bool hasResults = false;
private int resultCount = 0;
private void OnSearchCompleted(List<RequestStatusResponseModel> results)
{
hasResults = results.Any();
resultCount = results.Count;
}
}
Integrare în dashboard
<FodGrid Container="true" Spacing="3">
<FodGrid Item="true" xs="12" md="8">
<FodCard>
<FodCardHeader>
<FodText Typo="Typo.h5">
Verificare rapidă status cerere
</FodText>
</FodCardHeader>
<FodCardContent>
<FodRequestStatus
ShowAlert="false"
InitialKeyword="@lastSearchedKeyword" />
</FodCardContent>
</FodCard>
</FodGrid>
<FodGrid Item="true" xs="12" md="4">
<FodCard>
<FodCardContent>
<FodText Typo="Typo.h6" GutterBottom="true">
Căutări recente
</FodText>
<FodList>
@foreach (var search in recentSearches)
{
<FodListItem Button="true" OnClick="@(() => SearchAgain(search))">
<FodListItemText Primary="@search.Keyword"
Secondary="@search.Date.ToString("dd.MM.yyyy HH:mm")" />
</FodListItem>
}
</FodList>
</FodCardContent>
</FodCard>
</FodGrid>
</FodGrid>
Customizare afișare rezultate
<!-- Custom response display -->
@if (searchResults != null)
{
<div class="custom-results mt-4">
@foreach (var result in searchResults)
{
<FodCard Class="mb-3">
<FodCardHeader>
<div class="d-flex justify-content-between align-items-center">
<FodText Typo="Typo.h6">
Cerere: @result.OrderNumber
</FodText>
<FodChip Color="@GetStatusColor(result.Status)" Size="Size.Small">
@result.Status
</FodChip>
</div>
</FodCardHeader>
<FodCardContent>
<FodGrid Container="true" Spacing="2">
<FodGrid Item="true" xs="12" sm="6">
<FodText Typo="Typo.body2" Color="Color.Secondary">
Data depunerii
</FodText>
<FodText Typo="Typo.body1">
@result.SubmissionDate.ToString("dd MMMM yyyy")
</FodText>
</FodGrid>
<FodGrid Item="true" xs="12" sm="6">
<FodText Typo="Typo.body2" Color="Color.Secondary">
Termen estimat
</FodText>
<FodText Typo="Typo.body1">
@result.EstimatedResolveDate?.ToString("dd MMMM yyyy")
</FodText>
</FodGrid>
</FodGrid>
@if (result.RequiresDelivery && result.Delivery != null)
{
<FodAlert Severity="Severity.Info" Class="mt-3">
<FodAlertTitle>Informații livrare</FodAlertTitle>
Curier: @result.Delivery.CarrierName<br/>
Tracking: @result.Delivery.TrackingId
</FodAlert>
}
</FodCardContent>
<FodCardActions>
<FodButton Color="Color.Primary" OnClick="@(() => ShowDetails(result))">
Vezi detalii complete
</FodButton>
</FodCardActions>
</FodCard>
}
</div>
}
@code {
private Color GetStatusColor(string status)
{
return status switch
{
"Finalizat" => Color.Success,
"În procesare" => Color.Info,
"În așteptare" => Color.Warning,
"Respins" => Color.Error,
_ => Color.Default
};
}
}
6. Stilizare și personalizare
/* Stiluri pentru componenta de status */
.service-request-status-response {
margin-top: 2rem;
}
/* Panouri expandabile personalizate */
.fod-expansion-panel {
border-left: 4px solid var(--fod-palette-primary-main);
margin-bottom: 1rem;
}
/* Status badges */
.status-badge {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 12px;
font-size: 0.875rem;
font-weight: 500;
}
.status-badge.completed {
background-color: #4caf50;
color: white;
}
.status-badge.processing {
background-color: #2196f3;
color: white;
}
.status-badge.waiting {
background-color: #ff9800;
color: white;
}
/* Rezultate cu hover effect */
.result-item:hover {
background-color: rgba(0, 0, 0, 0.04);
cursor: pointer;
}
/* Timeline pentru status */
.status-timeline {
position: relative;
padding-left: 30px;
}
.status-timeline::before {
content: '';
position: absolute;
left: 10px;
top: 0;
bottom: 0;
width: 2px;
background: #e0e0e0;
}
.status-timeline-item {
position: relative;
padding-bottom: 1.5rem;
}
.status-timeline-item::before {
content: '';
position: absolute;
left: -24px;
top: 4px;
width: 12px;
height: 12px;
border-radius: 50%;
background: #2196f3;
border: 2px solid white;
}
7. Localizare
Componentele folosesc sistemul de localizare FOD. Cheile principale:
{
"Request_Status": "Verificare status cerere",
"RequestStatus_General_Text": "Introduceți numărul cererii sau codul serviciului pentru a verifica statusul",
"Search": "Caută",
"RequestStatus_Error_Text": "Nu s-au găsit rezultate pentru căutarea dvs.",
"OrderNumber": "Număr cerere",
"ServiceProviderNumber": "Cod furnizor serviciu",
"Status": "Status",
"ServiceName": "Nume serviciu",
"ReceptionMode": "Mod recepționare",
"Pickup_Location_Name": "Locație ridicare",
"Pickup_Location_Address": "Adresă",
"MCabinetRelease": "Disponibil în MCabinet",
"EstimatedResolveDate_Label": "Termen estimat rezolvare",
"SubmissionDate": "Data depunerii"
}
8. Integrare cu alte componente
Cu notificări
@inject ISnackbar Snackbar
<FodRequestStatus OnSearchCompleted="HandleSearchCompleted" />
@code {
private void HandleSearchCompleted(List<RequestStatusResponseModel> results)
{
if (!results.Any())
{
Snackbar.Add("Nu s-au găsit rezultate", Severity.Warning);
}
else
{
Snackbar.Add($"S-au găsit {results.Count} cereri", Severity.Success);
}
}
}
Cu export date
<FodToolbar>
<FodText Typo="Typo.h6">Rezultate căutare</FodText>
<FodSpacer />
<FodButton StartIcon="@Icons.Material.Filled.FileDownload"
OnClick="ExportResults">
Export CSV
</FodButton>
</FodToolbar>
<FodRequestStatusResponse Model="@searchResults" />
@code {
private async Task ExportResults()
{
var csv = GenerateCsv(searchResults);
await JS.InvokeVoidAsync("downloadFile", "rezultate.csv", csv);
}
}
9. Validare și erori
<!-- Validare custom -->
<FodRequestStatus>
<ValidationTemplate>
<DataAnnotationsValidator />
<CustomValidator @ref="customValidator" />
</ValidationTemplate>
</FodRequestStatus>
@code {
private CustomValidator customValidator;
private class CustomValidator : ComponentBase
{
[CascadingParameter]
private EditContext EditContext { get; set; }
protected override void OnInitialized()
{
EditContext.OnValidationRequested += (s, e) =>
{
var model = EditContext.Model as RequestStatusRequestModel;
if (model != null && model.Keyword?.Length < 3)
{
var messages = new ValidationMessageStore(EditContext);
messages.Add(() => model.Keyword,
"Cuvântul cheie trebuie să aibă cel puțin 3 caractere");
EditContext.NotifyValidationStateChanged();
}
};
}
}
}
10. Performanță și optimizare
- Paginare - Rezultatele sunt paginate automat pentru performanță
- Lazy loading - Detaliile sunt încărcate doar când panoul este expandat
- Caching - Rezultatele pot fi cache-uite local
// Service cu caching
public class CachedRequestStatusService : IRequestStatusService
{
private readonly IMemoryCache _cache;
private readonly IRequestStatusService _innerService;
public async Task<IEnumerable<RequestStatusResponseModel>> Search(
RequestStatusRequestModel request)
{
var cacheKey = $"request_status_{request.Keyword}";
if (!_cache.TryGetValue(cacheKey, out List<RequestStatusResponseModel> cached))
{
cached = (await _innerService.Search(request)).ToList();
_cache.Set(cacheKey, cached, TimeSpan.FromMinutes(5));
}
return cached;
}
}
11. Accesibilitate
- Suport pentru screen readers prin atribute ARIA
- Navigare cu tastatura pentru toate elementele interactive
- Indicatori vizuali clari pentru starea cererii
- Contrast adecvat pentru toate textele
12. Bune practici
- Validare input - Validați întotdeauna inputul înainte de căutare
- Feedback vizual - Afișați loading state în timpul căutării
- Mesaje clare - Folosiți mesaje localizate și descriptive
- Error handling - Gestionați erorile de rețea elegant
@try
{
<FodRequestStatus OnSearchError="HandleSearchError" />
}
catch (Exception ex)
{
<FodAlert Severity="Severity.Error">
A apărut o eroare. Vă rugăm încercați din nou.
</FodAlert>
}
@code {
private void HandleSearchError(Exception ex)
{
Logger.LogError(ex, "Eroare la căutarea statusului");
// Afișare mesaj utilizator
}
}
13. Troubleshooting
Căutarea nu returnează rezultate
- Verificați formatul cuvântului cheie
- Verificați conexiunea la serviciul backend
- Verificați că serviciul IRequestStatusService este înregistrat
Paginarea nu funcționează
- Verificați că Model conține toate rezultatele
- Verificați că PageSize este configurat corect
Localizarea nu funcționează
- Verificați că resursele de localizare sunt configurate
- Verificați cultura curentă a aplicației
14. Exemple avansate
Monitorizare automată status
@implements IDisposable
<FodRequestStatus @ref="statusComponent" />
@if (isMonitoring)
{
<FodAlert Severity="Severity.Info">
<FodAlertTitle>Monitorizare activă</FodAlertTitle>
Statusul este verificat automat la fiecare @refreshInterval secunde
</FodAlert>
}
@code {
private FodRequestStatus statusComponent;
private Timer refreshTimer;
private bool isMonitoring = false;
private int refreshInterval = 60;
private void StartMonitoring(string keyword)
{
isMonitoring = true;
refreshTimer = new Timer(async _ =>
{
await InvokeAsync(async () =>
{
await statusComponent.SearchAsync(keyword);
StateHasChanged();
});
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(refreshInterval));
}
public void Dispose()
{
refreshTimer?.Dispose();
}
}
Integrare cu notificări push
@inject INotificationService NotificationService
<FodRequestStatus OnSearchCompleted="CheckForStatusChanges" />
@code {
private Dictionary<string, string> previousStatuses = new();
private async Task CheckForStatusChanges(
List<RequestStatusResponseModel> results)
{
foreach (var result in results)
{
if (previousStatuses.TryGetValue(result.OrderNumber, out var prevStatus))
{
if (prevStatus != result.Status)
{
await NotificationService.SendNotification(
$"Statusul cererii {result.OrderNumber} s-a schimbat: {result.Status}",
NotificationType.StatusChange
);
}
}
previousStatuses[result.OrderNumber] = result.Status;
}
}
}
15. Concluzie
FodRequestStatus
și FodRequestStatusResponse
oferă o soluție completă pentru verificarea statusului cererilor în sistemul FOD. Cu suport pentru căutare, paginare, afișare detaliată și localizare, aceste componente sunt esențiale pentru transparența proceselor administrative și oferirea de feedback în timp real cetățenilor despre cererile lor.