Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 016b259da0 | |||
| bb789e443e | |||
| 392e038913 | |||
| d7f25efce2 | |||
| 5246d8c1ba | |||
| c2c07c6b89 |
@@ -73,10 +73,14 @@ jobs:
|
||||
|
||||
# Apply manifests and restart
|
||||
sshpass -e ssh -o StrictHostKeyChecking=no root@${{ env.K8S_SERVER }} "
|
||||
kubectl apply -f /tmp/frontoffice-deployment.yaml &&
|
||||
crictl rmi ${REGISTRY}/${IMAGE_NAME}:latest 2>/dev/null || true &&
|
||||
kubectl rollout restart deployment/frontoffice &&
|
||||
kubectl rollout status deployment/frontoffice --timeout=180s &&
|
||||
kubectl apply -n kbs-stage -f /tmp/frontoffice-deployment.yaml &&
|
||||
# Drop cached :latest so IfNotPresent/Always both pick the new digest
|
||||
# (crictl is broken on this host — use containerd ctr)
|
||||
ctr -n k8s.io images ls -q | grep -E 'frontoffice(:latest|@)' | while read -r ref; do
|
||||
ctr -n k8s.io images rm \"\$ref\" 2>/dev/null || true
|
||||
done
|
||||
kubectl -n kbs-stage rollout restart deployment/frontoffice &&
|
||||
kubectl -n kbs-stage rollout status deployment/frontoffice --timeout=180s &&
|
||||
rm -f /tmp/frontoffice-deployment.yaml
|
||||
"
|
||||
echo "✅ Deployed!"
|
||||
|
||||
@@ -4,7 +4,7 @@ apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: frontoffice
|
||||
namespace: default
|
||||
namespace: kbs-stage
|
||||
labels:
|
||||
app: frontoffice
|
||||
environment: staging
|
||||
@@ -21,6 +21,7 @@ spec:
|
||||
containers:
|
||||
- name: frontoffice
|
||||
image: 185.252.31.44:30080/admin/frontoffice:latest
|
||||
# Staging uses :latest — Always avoids stale node cache after registry retag
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 80
|
||||
@@ -43,7 +44,7 @@ apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: frontoffice-svc
|
||||
namespace: default
|
||||
namespace: kbs-stage
|
||||
labels:
|
||||
app: frontoffice
|
||||
spec:
|
||||
@@ -54,3 +55,31 @@ spec:
|
||||
targetPort: 80
|
||||
name: http
|
||||
type: ClusterIP
|
||||
|
||||
---
|
||||
# FrontOffice Ingress
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: frontoffice-ingress
|
||||
namespace: kbs-stage
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- frontoffice.se.kbs1.ir
|
||||
secretName: frontoffice-tls
|
||||
rules:
|
||||
- host: frontoffice.se.kbs1.ir
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: frontoffice-svc
|
||||
port:
|
||||
number: 80
|
||||
|
||||
@@ -94,8 +94,47 @@
|
||||
}
|
||||
|
||||
@* ═══════════════════════════════════════════════
|
||||
2. HOW IT WORKS — 3 numbered steps
|
||||
1c. TWENTYCARD CREDIT — promo box
|
||||
═══════════════════════════════════════════════ *@
|
||||
<section class="py-4" style="background:var(--mud-palette-surface);">
|
||||
<MudContainer MaxWidth="MaxWidth.Medium">
|
||||
<MudPaper Elevation="0" Class="landing-twentycard-box rounded-xl pa-4 pa-md-5">
|
||||
<MudStack Row="true" Spacing="3" AlignItems="AlignItems.Start" Class="flex-wrap">
|
||||
<MudAvatar Color="Color.Info" Variant="Variant.Filled" Size="Size.Large" Class="rounded-lg" Style="min-width:56px;">
|
||||
<MudIcon Icon="@Icons.Material.Filled.AccountBalance" />
|
||||
</MudAvatar>
|
||||
<MudStack Spacing="2" Style="flex:1; min-width:220px;">
|
||||
<MudText Typo="Typo.h6">تأمین اعتبار ۲۰کارت</MudText>
|
||||
<MudText Typo="Typo.body2" Class="mud-text-secondary">
|
||||
با تأمین اعتبار از طریق ۲۰کارت میتوانید بدون پرداخت نقدی کامل، هزینه خرید پکیج و محصولات در کارا بازار را پوشش دهید.
|
||||
فرایند درخواست و تأیید اعتبار در پنل ۲۰کارت انجام میشود و پس از آن پرداخت از همان مسیر در دسترس است.
|
||||
این روش برای کسانی مناسب است که میخواهند سریعتر وارد مسیر عضویت و خرید شوند.
|
||||
</MudText>
|
||||
<MudText Typo="Typo.body2">
|
||||
بعد از دریافت وام، میتوانید در کارا بازار از باشگاه مشتریان استفاده کنید و با فروش و دعوت، توسعه سرمایه داشته باشید.
|
||||
</MudText>
|
||||
<div class="mt-1">
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Info"
|
||||
Class="rounded-pill"
|
||||
StartIcon="@Icons.Material.Filled.OpenInNew"
|
||||
Disabled="@string.IsNullOrWhiteSpace(_twentyCardPortalUrl)"
|
||||
OnClick="OpenTwentyCardPortal">
|
||||
ورود به سایت ۲۰کارت
|
||||
</MudButton>
|
||||
</div>
|
||||
</MudStack>
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
</MudContainer>
|
||||
</section>
|
||||
|
||||
@* ═══════════════════════════════════════════════
|
||||
2. HOW IT WORKS — 3 numbered steps
|
||||
(appsettings Landing:ShowStepsSection; default false)
|
||||
═══════════════════════════════════════════════ *@
|
||||
@if (_showStepsSection)
|
||||
{
|
||||
<section class="section-landing">
|
||||
<MudContainer MaxWidth="MaxWidth.Large">
|
||||
<div class="text-center mb-8 fade-in-up">
|
||||
@@ -121,10 +160,14 @@
|
||||
</MudGrid>
|
||||
</MudContainer>
|
||||
</section>
|
||||
}
|
||||
|
||||
@* ═══════════════════════════════════════════════
|
||||
3. FEATURES — 6 cards with icons
|
||||
(appsettings Landing:ShowFeaturesSection; default false)
|
||||
═══════════════════════════════════════════════ *@
|
||||
@if (_showFeaturesSection)
|
||||
{
|
||||
<section class="section-landing" style="background:var(--mud-palette-background-gray);">
|
||||
<MudContainer MaxWidth="MaxWidth.Large">
|
||||
<div class="text-center mb-8 fade-in-up">
|
||||
@@ -152,6 +195,7 @@
|
||||
</MudGrid>
|
||||
</MudContainer>
|
||||
</section>
|
||||
}
|
||||
|
||||
@* ═══════════════════════════════════════════════
|
||||
4. STATS — Counter cards
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using FrontOffice.Main.Utilities;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.JSInterop;
|
||||
using MudBlazor;
|
||||
|
||||
@@ -16,8 +17,12 @@ public partial class Index : IDisposable
|
||||
[Inject] private DiscountCartService DiscountCart { get; set; } = default!;
|
||||
[Inject] private GuestActionGate GuestGate { get; set; } = default!;
|
||||
[Inject] private VATService VAT { get; set; } = default!;
|
||||
[Inject] private IConfiguration Configuration { get; set; } = default!;
|
||||
|
||||
private bool _isAuthenticated;
|
||||
private string _twentyCardPortalUrl = string.Empty;
|
||||
private bool _showStepsSection;
|
||||
private bool _showFeaturesSection;
|
||||
|
||||
// ── CMS page data ──
|
||||
private PageSettingsDto? _pageData;
|
||||
@@ -49,6 +54,10 @@ public partial class Index : IDisposable
|
||||
{
|
||||
MainService.OnChangeHandler += OnStateChanged;
|
||||
_isAuthenticated = await AuthService.IsAuthenticatedAsync();
|
||||
_twentyCardPortalUrl = Configuration["TwentyCard:CreditPortalUrl"] ?? string.Empty;
|
||||
// appsettings Landing:* — default false (hidden). Set true to restore sections.
|
||||
_showStepsSection = Configuration.GetValue("Landing:ShowStepsSection", false);
|
||||
_showFeaturesSection = Configuration.GetValue("Landing:ShowFeaturesSection", false);
|
||||
|
||||
// Load landing page settings from CMS
|
||||
try
|
||||
@@ -298,6 +307,12 @@ public partial class Index : IDisposable
|
||||
Navigation.NavigateTo(RouteConstants.Registration.Wizard);
|
||||
}
|
||||
|
||||
private async Task OpenTwentyCardPortal()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_twentyCardPortalUrl)) return;
|
||||
await JS.InvokeVoidAsync("open", _twentyCardPortalUrl, "_blank");
|
||||
}
|
||||
|
||||
private void NavigateToPost(string slug)
|
||||
{
|
||||
Navigation.NavigateTo($"/blog/{slug}");
|
||||
@@ -334,8 +349,10 @@ public partial class Index : IDisposable
|
||||
public string? HeroButtonPrimaryText { get; set; }
|
||||
public string? HeroButtonSecondaryText { get; set; }
|
||||
public List<TrustBadgeItem>? TrustBadges { get; set; }
|
||||
public bool? StepsEnabled { get; set; }
|
||||
public string? StepsTitle { get; set; }
|
||||
public List<StepItem>? Steps { get; set; }
|
||||
public bool? FeaturesEnabled { get; set; }
|
||||
public string? FeaturesTitle { get; set; }
|
||||
public List<FeatureItem>? Features { get; set; }
|
||||
public string? StatsTitle { get; set; }
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
"TwentyCard": {
|
||||
"CreditPortalUrl": "https://userpanel.20card.ir/"
|
||||
},
|
||||
"Landing": {
|
||||
"ShowStepsSection": false,
|
||||
"ShowFeaturesSection": false
|
||||
},
|
||||
"EncryptionSettings": {
|
||||
"Key": "kmcQ3XTmH4mrdh8VHziuscyf8LLYjG//Kyni81nH/0E=",
|
||||
"IV": "1wyF3Tt142MOkCpIyCxh/g=="
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
"TwentyCard": {
|
||||
"CreditPortalUrl": "https://userpanel.20card.ir/"
|
||||
},
|
||||
"Landing": {
|
||||
"ShowStepsSection": false,
|
||||
"ShowFeaturesSection": false
|
||||
},
|
||||
"EncryptionSettings": {
|
||||
"Key": "kmcQ3XTmH4mrdh8VHziuscyf8LLYjG//Kyni81nH/0E=",
|
||||
"IV": "1wyF3Tt142MOkCpIyCxh/g=="
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
"TwentyCard": {
|
||||
"CreditPortalUrl": "https://userpanel.20card.ir/"
|
||||
},
|
||||
"Landing": {
|
||||
"ShowStepsSection": false,
|
||||
"ShowFeaturesSection": false
|
||||
},
|
||||
"EncryptionSettings": {
|
||||
"Key": "kmcQ3XTmH4mrdh8VHziuscyf8LLYjG//Kyni81nH/0E=",
|
||||
"IV": "1wyF3Tt142MOkCpIyCxh/g=="
|
||||
|
||||
@@ -1617,6 +1617,12 @@ html, body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ── Landing TwentyCard credit promo ── */
|
||||
.landing-twentycard-box {
|
||||
background: var(--ds-info-soft);
|
||||
border: 1px solid rgba(59, 130, 246, 0.22);
|
||||
}
|
||||
|
||||
/* ── Register Wizard Unified ── */
|
||||
.wizard-section {
|
||||
min-height: 80vh;
|
||||
|
||||
Reference in New Issue
Block a user