feat(web-client-tpos): replace hardcoded store pages with real API data

- Rewrite StoreList.razor with real data from PosDataService
- Rewrite StoreDetail.razor with real shop data from BFF
- Rewrite StoreSettings.razor with editable form bound to real data
- Add GetShopByIdAsync to PosDataService and BFF endpoint
- Add UpdateShopAsync to MerchantApiService
- Add ShopUpdateDto to MerchantDtos
- Fix BFF DB connection: configurable via env vars (BFF_DB_HOST)
- Add BFF_DB env vars to docker-compose.yml
This commit is contained in:
Ho Ngoc Hai
2026-02-28 04:23:11 +07:00
parent 1e211dec27
commit 12be9737d9
8 changed files with 756 additions and 557 deletions

View File

@@ -8,8 +8,15 @@ namespace WebClientTpos.Server.Controllers;
[Route("api/bff")]
public class BffDataController : ControllerBase
{
// EN: DB host configurable via env var (Docker: "postgres", dev: "localhost")
// VI: DB host cấu hình qua env var (Docker: "postgres", dev: "localhost")
private static readonly string _dbHost = Environment.GetEnvironmentVariable("BFF_DB_HOST") ?? "localhost";
private static readonly string _dbPort = Environment.GetEnvironmentVariable("BFF_DB_PORT") ?? "5432";
private static readonly string _dbUser = Environment.GetEnvironmentVariable("BFF_DB_USER") ?? "goodgo";
private static readonly string _dbPass = Environment.GetEnvironmentVariable("BFF_DB_PASS") ?? "goodgo_dev_2024";
private static string ConnStr(string db) =>
$"Host=localhost;Port=5432;Database={db};Username=goodgo;Password=goodgo_dev_2024";
$"Host={_dbHost};Port={_dbPort};Database={db};Username={_dbUser};Password={_dbPass}";
[HttpGet("shops")]
public async Task<IActionResult> GetShops()
@@ -27,6 +34,26 @@ public class BffDataController : ControllerBase
return Ok(shops);
}
[HttpGet("shops/{shopId:guid}")]
public async Task<IActionResult> GetShopById(Guid shopId)
{
await using var conn = new NpgsqlConnection(ConnStr("merchant_service"));
var shop = await conn.QueryFirstOrDefaultAsync<dynamic>(
@"SELECT s.id, s.name, s.slug, s.description, s.phone, s.email,
s.open_time, s.close_time,
bc.name as category, st.name as status
FROM shops s
JOIN business_categories bc ON s.category_id = bc.id
JOIN shop_statuses st ON s.status_id = st.id
WHERE s.id = @ShopId AND s.is_deleted = false",
new { ShopId = shopId });
if (shop == null)
return NotFound(new { message = "Shop not found" });
return Ok(shop);
}
[HttpGet("shops/{shopId}/products")]
public async Task<IActionResult> GetProducts(Guid shopId)
{