using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Primitives;
namespace FrontOffice.Main.Utilities;
public enum ProductSortOption
{
PriceDesc,
PriceAsc,
Newest,
Title
}
///
/// وضعیت لیست فروشگاه در query string — فقط برای /products و /discount-store.
///
public sealed class ShopListQueryState
{
public string Query { get; init; } = string.Empty;
public string? Sort { get; init; }
public long? CategoryId { get; init; }
public int Pages { get; init; } = 1;
public static ShopListQueryState Parse(Uri uri)
{
var q = QueryHelpers.ParseQuery(uri.Query);
return new ShopListQueryState
{
Query = GetString(q, "q") ?? string.Empty,
Sort = GetString(q, "sort"),
CategoryId = GetLong(q, "category"),
Pages = Math.Max(1, GetInt(q, "pages") ?? 1)
};
}
public string ToRelativeUrl(string path)
{
var dict = new Dictionary();
if (!string.IsNullOrWhiteSpace(Query))
dict["q"] = Query.Trim();
if (!string.IsNullOrWhiteSpace(Sort) && !string.Equals(Sort, "price-desc", StringComparison.OrdinalIgnoreCase))
dict["sort"] = Sort;
if (CategoryId is > 0)
dict["category"] = CategoryId.Value.ToString();
if (Pages > 1)
dict["pages"] = Pages.ToString();
return dict.Count == 0
? path
: QueryHelpers.AddQueryString(path, dict!);
}
public bool Matches(ShopListQueryState other) =>
string.Equals(Query?.Trim() ?? "", other.Query?.Trim() ?? "", StringComparison.Ordinal)
&& string.Equals(NormalizeSort(Sort), NormalizeSort(other.Sort), StringComparison.OrdinalIgnoreCase)
&& CategoryId == other.CategoryId
&& Pages == other.Pages;
public static string NormalizeSort(string? sort) =>
string.IsNullOrWhiteSpace(sort) ? "price-desc" : sort.Trim().ToLowerInvariant();
public static string ToSortKey(ProductSortOption option) => option switch
{
ProductSortOption.PriceAsc => "price-asc",
ProductSortOption.Newest => "newest",
ProductSortOption.Title => "title",
_ => "price-desc"
};
public static ProductSortOption ParseSortOption(string? sort) => NormalizeSort(sort) switch
{
"price-asc" => ProductSortOption.PriceAsc,
"newest" => ProductSortOption.Newest,
"title" => ProductSortOption.Title,
_ => ProductSortOption.PriceDesc
};
public static string ToApiSortBy(ProductSortOption option) => option switch
{
ProductSortOption.PriceAsc => "price asc",
ProductSortOption.Newest => "id desc",
ProductSortOption.Title => "title asc",
_ => "price desc"
};
private static string? GetString(Dictionary q, string key) =>
q.TryGetValue(key, out var v) ? v.FirstOrDefault() : null;
private static long? GetLong(Dictionary q, string key) =>
long.TryParse(GetString(q, key), out var n) ? n : null;
private static int? GetInt(Dictionary q, string key) =>
int.TryParse(GetString(q, key), out var n) ? n : null;
}