From c5e7d1dead9d5d20aa5fc3f475d53670acdac7a5 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 20 Sep 2026 23:35:33 +0330 Subject: [PATCH 1/5] feat(nav-menu): add link to Invitations Report in navigation menu - Introduced a new navigation link for the Invitations Report page in NavMenu.razor. - Updated RouteConstance.cs to include the new InvitationsReport constant. - Made minor adjustments to .gitignore for improved clarity. --- .gitignore | 4 +- .../Common/Utilities/RouteConstance.cs | 1 + .../Pages/User/InvitationsReportPage.razor | 85 +++++++++++++++++++ .../Pages/User/InvitationsReportPage.razor.cs | 74 ++++++++++++++++ src/BackOffice/Shared/NavMenu.razor | 5 ++ 5 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 src/BackOffice/Pages/User/InvitationsReportPage.razor create mode 100644 src/BackOffice/Pages/User/InvitationsReportPage.razor.cs diff --git a/.gitignore b/.gitignore index 3508f6e..2f9a25a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,10 @@ # ---> VisualStudio ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. -## +## ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore -# User-specific files +# User-specific files *.rsuser *.suo *.user diff --git a/src/BackOffice/Common/Utilities/RouteConstance.cs b/src/BackOffice/Common/Utilities/RouteConstance.cs index 9da68a5..6298da1 100644 --- a/src/BackOffice/Common/Utilities/RouteConstance.cs +++ b/src/BackOffice/Common/Utilities/RouteConstance.cs @@ -8,6 +8,7 @@ public static class RouteConstance public const string Package = "/PackagePage/"; public const string Role = "/RolePage/"; public const string UserPage = "/UserPage/"; + public const string InvitationsReport = "/InvitationsReportPage/"; public const string UserOrder = "/UserOrderPage/"; public const string Orders = "/OrdersPage/"; public const string OrdersSalesReports = "/OrdersSalesReportsPage/"; diff --git a/src/BackOffice/Pages/User/InvitationsReportPage.razor b/src/BackOffice/Pages/User/InvitationsReportPage.razor new file mode 100644 index 0000000..ebf2740 --- /dev/null +++ b/src/BackOffice/Pages/User/InvitationsReportPage.razor @@ -0,0 +1,85 @@ +@attribute [Route(RouteConstance.InvitationsReport)] +@using CMSMicroservice.Protobuf.Protos.User +@using BackOffice.Common.BaseComponents +@using DataModel = CMSMicroservice.Protobuf.Protos.User.InvitationReportModel + + + + + + + + + + + + + + + + + + + + + + + + همه + فعال + غیرفعال + + + + + + + گزارش دعوت‌ها (جدیدترین اول) + + + + + + @($"{context.Item.InviterFirstName} {context.Item.InviterLastName}".Trim()) + @context.Item.InviterMobile + + + + + @($"{context.Item.InviteeFirstName} {context.Item.InviteeLastName}".Trim()) + @context.Item.InviteeMobile + + + + + @(context.Item.InviteeRegisteredAt?.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd HH:mm") ?? "—") + + + + + @if (context.Item.InviteeClubActive) + { + فعال + } + else + { + غیرفعال + } + + + + + @(context.Item.InvitedAt?.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd HH:mm") ?? "—") + + + + + + + + موردی یافت نشد + + + + diff --git a/src/BackOffice/Pages/User/InvitationsReportPage.razor.cs b/src/BackOffice/Pages/User/InvitationsReportPage.razor.cs new file mode 100644 index 0000000..fd37548 --- /dev/null +++ b/src/BackOffice/Pages/User/InvitationsReportPage.razor.cs @@ -0,0 +1,74 @@ +using CMSMicroservice.Protobuf.Protos.User; +using BackOffice.Common.BaseComponents; +using Microsoft.AspNetCore.Components; +using MudBlazor; +using DataModel = CMSMicroservice.Protobuf.Protos.User.InvitationReportModel; + +namespace BackOffice.Pages.User; + +public partial class InvitationsReportPage +{ + [Inject] public UserContract.UserContractClient UserContract { get; set; } = default!; + + private MudDataGrid _gridData = default!; + private BasePageComponent _basePage = default!; + private GetInvitationsByFilterRequest _request = new() { Filter = new() }; + private string _clubActiveFilter = string.Empty; + + private async Task> ServerReload(GridState state) + { + _request.Filter ??= new(); + ApplyClubFilter(); + _request.PaginationState ??= new(); + _request.PaginationState.PageNumber = state.Page + 1; + _request.PaginationState.PageSize = state.PageSize; + _request.SortBy = "newest"; + + var result = await UserContract.GetInvitationsByFilterAsync(_request); + if (result?.Models != null && result.Models.Any()) + { + return new GridData + { + Items = result.Models.ToList(), + TotalItems = (int)result.MetaData.TotalCount + }; + } + + return new GridData(); + } + + private void ApplyClubFilter() + { + _request.Filter ??= new(); + if (_clubActiveFilter == "true") + _request.Filter.InviteeClubActive = true; + else if (_clubActiveFilter == "false") + _request.Filter.InviteeClubActive = false; + else + _request.Filter.InviteeClubActive = null; + } + + private void ReLoadData() + { + _ = _gridData.ReloadServerData(); + } + + public async Task OnFilterSubmit() + { + ApplyClubFilter(); + _basePage.IsFiltered = true; + StateHasChanged(); + ReLoadData(); + await Task.CompletedTask; + } + + public async Task OnFilterCleared() + { + _basePage.IsFiltered = false; + _clubActiveFilter = string.Empty; + _request = new() { Filter = new() }; + StateHasChanged(); + ReLoadData(); + await Task.CompletedTask; + } +} diff --git a/src/BackOffice/Shared/NavMenu.razor b/src/BackOffice/Shared/NavMenu.razor index c2c9776..4e825a7 100644 --- a/src/BackOffice/Shared/NavMenu.razor +++ b/src/BackOffice/Shared/NavMenu.razor @@ -185,6 +185,11 @@ Icon="@Icons.Material.Filled.People"> کاربران + + گزارش دعوت‌ها + } @if (CanManageRoles) From fc006ed73134f3cc04eb9826ae89be3cf2964fcb Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Tue, 22 Sep 2026 21:41:15 +0330 Subject: [PATCH 2/5] fix(deps): bump CMS Protobuf to 0.0.213 for invitation report types Co-authored-by: Cursor --- src/BackOffice/BackOffice.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BackOffice/BackOffice.csproj b/src/BackOffice/BackOffice.csproj index 29ae5c3..4fc3546 100644 --- a/src/BackOffice/BackOffice.csproj +++ b/src/BackOffice/BackOffice.csproj @@ -143,7 +143,7 @@ - + From 059920e7829cb113bab31473d40300b42095c406 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Tue, 22 Sep 2026 22:18:43 +0330 Subject: [PATCH 3/5] chore(staging): point registry and K8S to 185.252.31.44 after server migration --- .gitea/workflows/kub-deploy.yml | 10 +++++----- .gitea/workflows/prod-deploy.yml | 8 ++++---- k8s/staging/backoffice-deployment.yaml | 2 +- src/BackOffice/Dockerfile | 4 ++-- src/BackOffice/NuGet.config | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.gitea/workflows/kub-deploy.yml b/.gitea/workflows/kub-deploy.yml index 8e355fe..6c3a65f 100644 --- a/.gitea/workflows/kub-deploy.yml +++ b/.gitea/workflows/kub-deploy.yml @@ -6,15 +6,15 @@ on: - kub-stage env: - REGISTRY: 194.5.195.53:30080 + REGISTRY: 185.252.31.44:30080 IMAGE_NAME: admin/backoffice - K8S_SERVER: 194.5.195.53 + K8S_SERVER: 185.252.31.44 jobs: build-and-deploy: runs-on: ubuntu-latest container: - image: 194.5.195.53:32082/docker-sshpass:latest + image: 185.252.31.44:32082/docker-sshpass:latest options: --privileged steps: - name: Start Docker daemon @@ -22,7 +22,7 @@ jobs: mkdir -p /etc/docker cat > /etc/docker/daemon.json << 'DAEMON' { - "insecure-registries": ["194.5.195.53:30080", "194.5.195.53:32500", "194.5.195.53:32082"] + "insecure-registries": ["185.252.31.44:30080", "185.252.31.44:32500", "185.252.31.44:32082"] } DAEMON echo "🚀 Starting Docker daemon..." @@ -52,7 +52,7 @@ jobs: - name: Login to Docker registries run: | - echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login 194.5.195.53:32082 -u admin --password-stdin + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login 185.252.31.44:32082 -u admin --password-stdin echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u admin --password-stdin - name: Build Docker Image diff --git a/.gitea/workflows/prod-deploy.yml b/.gitea/workflows/prod-deploy.yml index 060dcf2..dd2628d 100644 --- a/.gitea/workflows/prod-deploy.yml +++ b/.gitea/workflows/prod-deploy.yml @@ -6,7 +6,7 @@ on: - production env: - REGISTRY: 194.5.195.53:30080 + REGISTRY: 185.252.31.44:30080 IMAGE_NAME: admin/backoffice K8S_SERVER: 45.149.79.127 @@ -14,7 +14,7 @@ jobs: build-and-deploy: runs-on: ubuntu-latest container: - image: 194.5.195.53:32082/docker-sshpass:latest + image: 185.252.31.44:32082/docker-sshpass:latest options: --privileged steps: - name: Start Docker daemon @@ -22,7 +22,7 @@ jobs: mkdir -p /etc/docker cat > /etc/docker/daemon.json << 'DAEMON' { - "insecure-registries": ["194.5.195.53:30080", "194.5.195.53:32500", "194.5.195.53:32082"] + "insecure-registries": ["185.252.31.44:30080", "185.252.31.44:32500", "185.252.31.44:32082"] } DAEMON echo "🚀 Starting Docker daemon..." @@ -50,7 +50,7 @@ jobs: - name: Login to Docker registries run: | - echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login 194.5.195.53:32082 -u admin --password-stdin + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login 185.252.31.44:32082 -u admin --password-stdin echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u admin --password-stdin - name: Build Docker Image diff --git a/k8s/staging/backoffice-deployment.yaml b/k8s/staging/backoffice-deployment.yaml index e905bc0..0b1e8e2 100644 --- a/k8s/staging/backoffice-deployment.yaml +++ b/k8s/staging/backoffice-deployment.yaml @@ -19,7 +19,7 @@ spec: spec: containers: - name: backoffice - image: 194.5.195.53:30080/admin/backoffice:latest + image: 185.252.31.44:30080/admin/backoffice:latest imagePullPolicy: Always ports: - containerPort: 80 diff --git a/src/BackOffice/Dockerfile b/src/BackOffice/Dockerfile index 2b8bac4..1a4ed0a 100644 --- a/src/BackOffice/Dockerfile +++ b/src/BackOffice/Dockerfile @@ -1,4 +1,4 @@ -FROM 194.5.195.53:32082/dotnet/sdk:9.0 AS build +FROM 185.252.31.44:32082/dotnet/sdk:9.0 AS build WORKDIR /src # Copy NuGet config and project file @@ -16,7 +16,7 @@ WORKDIR "/src/BackOffice" RUN dotnet publish "BackOffice.csproj" -c Release -o /app/publish # Runtime stage - nginx for Blazor WebAssembly -FROM 194.5.195.53:32082/nginx:alpine AS final +FROM 185.252.31.44:32082/nginx:alpine AS final WORKDIR /usr/share/nginx/html # Remove default nginx files diff --git a/src/BackOffice/NuGet.config b/src/BackOffice/NuGet.config index c53f59f..706d210 100644 --- a/src/BackOffice/NuGet.config +++ b/src/BackOffice/NuGet.config @@ -3,7 +3,7 @@ - + From 7c3ee765d4f5dee81ca725108a3844e45ab0b3e7 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Thu, 24 Sep 2026 19:53:57 +0330 Subject: [PATCH 4/5] feat(reports): enhance weekly and ledger transaction reports with additional package and user details - Added 'PackageTitle' to the weekly reports for better clarity on package information. - Updated CSV export for weekly reports to include package details. - Introduced 'UserId' and 'UserFullName' columns in ledger transaction reports for improved user tracking. - Modified CSV export for ledger transactions to reflect new user information. - Bumped Foursat.CMSMicroservice.Protobuf version to 0.0.214 for compatibility with recent changes. --- src/BackOffice/BackOffice.csproj | 2 +- .../Pages/Commission/WeeklyReports.razor | 9 +++++++++ .../Pages/Commission/WeeklyReports.razor.cs | 3 ++- .../Pages/Payment/LedgerTransactions.razor | 14 ++++++++++++-- src/BackOffice/Pages/Payment/Transactions.razor | 9 +++++++-- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/BackOffice/BackOffice.csproj b/src/BackOffice/BackOffice.csproj index 4fc3546..080f774 100644 --- a/src/BackOffice/BackOffice.csproj +++ b/src/BackOffice/BackOffice.csproj @@ -143,7 +143,7 @@ - + diff --git a/src/BackOffice/Pages/Commission/WeeklyReports.razor b/src/BackOffice/Pages/Commission/WeeklyReports.razor index b97d595..75df16b 100644 --- a/src/BackOffice/Pages/Commission/WeeklyReports.razor +++ b/src/BackOffice/Pages/Commission/WeeklyReports.razor @@ -65,6 +65,11 @@ SortMode="SortMode.Multiple"> + + + @(string.IsNullOrEmpty(context.Item.PackageTitle) ? "—" : context.Item.PackageTitle) + + @context.Item.TotalPoolAmount.ToString("N0") تومان @@ -203,6 +208,8 @@ { WeekDefinitionId = x.WeekDefinitionId, WeekDisplayName = x.WeekDisplayName, + PackageId = x.PackageId, + PackageTitle = x.PackageTitle, TotalPoolAmount = x.TotalPoolAmount, TotalBalances = x.TotalBalances, ValuePerBalance = x.ValuePerBalance, @@ -249,6 +256,8 @@ { public long WeekDefinitionId { get; set; } public string WeekDisplayName { get; set; } = ""; + public long PackageId { get; set; } + public string PackageTitle { get; set; } = ""; public long TotalPoolAmount { get; set; } public int TotalBalances { get; set; } public long ValuePerBalance { get; set; } diff --git a/src/BackOffice/Pages/Commission/WeeklyReports.razor.cs b/src/BackOffice/Pages/Commission/WeeklyReports.razor.cs index d9a8ff1..fb5f12d 100644 --- a/src/BackOffice/Pages/Commission/WeeklyReports.razor.cs +++ b/src/BackOffice/Pages/Commission/WeeklyReports.razor.cs @@ -18,12 +18,13 @@ public partial class WeeklyReports try { var sb = new StringBuilder(); - sb.AppendLine("هفته,مبلغ کل استخر,مجموع موجودی‌ها,ارزش هر موجودی,وضعیت,تاریخ محاسبه"); + sb.AppendLine("هفته,پکیج,مبلغ کل استخر,مجموع موجودی‌ها,ارزش هر موجودی,وضعیت,تاریخ محاسبه"); foreach (var r in _reports) { sb.AppendLine(string.Join(",", EscapeCsv(r.WeekDisplayName), + EscapeCsv(r.PackageTitle), r.TotalPoolAmount, r.TotalBalances, r.ValuePerBalance, diff --git a/src/BackOffice/Pages/Payment/LedgerTransactions.razor b/src/BackOffice/Pages/Payment/LedgerTransactions.razor index 5448f2a..f19cbd7 100644 --- a/src/BackOffice/Pages/Payment/LedgerTransactions.razor +++ b/src/BackOffice/Pages/Payment/LedgerTransactions.razor @@ -96,6 +96,16 @@ + + + @(context.Item.UserId != null ? context.Item.UserId.ToString() : "—") + + + + + @(string.IsNullOrWhiteSpace(context.Item.UserFullName) ? "—" : context.Item.UserFullName) + + @@ -232,13 +242,13 @@ Filter = BuildFilter() }); var sb = new System.Text.StringBuilder(); - sb.AppendLine("Id,Type,Amount,Description,Status,RefId,PaymentDate,Created"); + sb.AppendLine("Id,UserId,UserFullName,Type,Amount,Description,Status,RefId,PaymentDate,Created"); foreach (var r in result.Models) { var type = r.HasType ? ReportLabels.GetTransactionTypeLabel(r.Type) : ""; var status = r.HasPaymentStatus ? ReportLabels.GetTransactionPaymentStatusLabel(r.PaymentStatus) : ""; var paymentDate = r.PaymentDate != null ? r.PaymentDate.ToDateTime().ToString("yyyy-MM-dd HH:mm") : ""; - sb.AppendLine($"{r.Id},{type},{r.Amount},\"{r.Description}\",{status},{r.RefId},{paymentDate},{r.Created.ToDateTime():yyyy-MM-dd HH:mm}"); + sb.AppendLine($"{r.Id},{r.UserId},\"{r.UserFullName}\",{type},{r.Amount},\"{r.Description}\",{status},{r.RefId},{paymentDate},{r.Created.ToDateTime():yyyy-MM-dd HH:mm}"); } await jsRuntime.InvokeVoidAsync("jsSaveAsFile", "ledger-transactions.csv", sb.ToString()); } diff --git a/src/BackOffice/Pages/Payment/Transactions.razor b/src/BackOffice/Pages/Payment/Transactions.razor index f25ecd1..9967301 100644 --- a/src/BackOffice/Pages/Payment/Transactions.razor +++ b/src/BackOffice/Pages/Payment/Transactions.razor @@ -82,6 +82,11 @@ + + + @(string.IsNullOrWhiteSpace(context.Item.UserFullName) ? "—" : context.Item.UserFullName) + + @@ -193,9 +198,9 @@ Filter = BuildFilter() }); var sb = new System.Text.StringBuilder(); - sb.AppendLine("Id,UserId,Mobile,Gateway,Amount,Authority,RefId,Status,OrderId,Created"); + sb.AppendLine("Id,UserId,UserFullName,Mobile,Gateway,Amount,Authority,RefId,Status,OrderId,Created"); foreach (var r in result.Models) - sb.AppendLine($"{r.Id},{r.UserId},{r.Mobile},{r.GatewayProvider},{r.Amount},{r.Authority},{r.RefId},{r.PaymentStatus},{r.OrderId},{r.CreatedAt.ToDateTime():yyyy-MM-dd HH:mm}"); + sb.AppendLine($"{r.Id},{r.UserId},\"{r.UserFullName}\",{r.Mobile},{r.GatewayProvider},{r.Amount},{r.Authority},{r.RefId},{r.PaymentStatus},{r.OrderId},{r.CreatedAt.ToDateTime():yyyy-MM-dd HH:mm}"); await jsRuntime.InvokeVoidAsync("jsSaveAsFile", "payment-transactions.csv", sb.ToString()); } catch (Exception ex) { Snackbar.Add($"خطا در export: {ex.Message}", Severity.Error); } From 6d3295723660e5e220fdd2e2d4f8ac755162bdcf Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Thu, 24 Sep 2026 21:26:22 +0330 Subject: [PATCH 5/5] chore(k8s): deploy staging apps to namespace kbs-stage Co-authored-by: Cursor --- .gitea/workflows/kub-deploy.yml | 6 +++--- k8s/staging/backoffice-deployment.yaml | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.gitea/workflows/kub-deploy.yml b/.gitea/workflows/kub-deploy.yml index 6c3a65f..2b2fb69 100644 --- a/.gitea/workflows/kub-deploy.yml +++ b/.gitea/workflows/kub-deploy.yml @@ -73,9 +73,9 @@ jobs: # Apply manifests and restart sshpass -e ssh -o StrictHostKeyChecking=no root@${{ env.K8S_SERVER }} " - kubectl apply -f /tmp/backoffice-deployment.yaml && - kubectl rollout restart deployment/backoffice && - kubectl rollout status deployment/backoffice --timeout=180s && + kubectl apply -n kbs-stage -f /tmp/backoffice-deployment.yaml && + kubectl -n kbs-stage rollout restart deployment/backoffice && + kubectl -n kbs-stage rollout status deployment/backoffice --timeout=180s && rm -f /tmp/backoffice-deployment.yaml " echo "✅ Deployed!" diff --git a/k8s/staging/backoffice-deployment.yaml b/k8s/staging/backoffice-deployment.yaml index 0b1e8e2..336cd1d 100644 --- a/k8s/staging/backoffice-deployment.yaml +++ b/k8s/staging/backoffice-deployment.yaml @@ -4,7 +4,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: backoffice - namespace: default + namespace: kbs-stage labels: app: backoffice spec: @@ -20,7 +20,7 @@ spec: containers: - name: backoffice image: 185.252.31.44:30080/admin/backoffice:latest - imagePullPolicy: Always + imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: http @@ -43,7 +43,7 @@ apiVersion: v1 kind: Service metadata: name: backoffice-svc - namespace: default + namespace: kbs-stage spec: selector: app: backoffice @@ -58,7 +58,7 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: backoffice-ingress - namespace: default + namespace: kbs-stage annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" nginx.ingress.kubernetes.io/ssl-redirect: "true"