From c71ce473d2dcc18e110866495ba518f15fbde130 Mon Sep 17 00:00:00 2001 From: Zaza <181195712+Zazawowow@users.noreply.github.com> Date: Sun, 13 Sep 2026 23:09:30 +0200 Subject: [PATCH 1/4] Align web payment flow with Hub styling and payment plan controls --- .../Angor.Client/Pages/InvestView.razor | 628 ++++++++++-------- .../Angor.Client/Shared/EmptyLayout.razor | 22 +- .../Shared/HubPaymentHeader.razor | 75 +++ .../Shared/PasswordComponent.razor | 2 +- .../assets/css/hub-invest-controls.css | 613 +++++++++++++++++ .../wwwroot/assets/css/invest.css | 395 ++++++++++- .../fonts/proxima-nova/proximanova_bold.otf | Bin 0 -> 96640 bytes .../fonts/proxima-nova/proximanova_light.otf | Bin 0 -> 62492 bytes .../wwwroot/assets/img/app-icon.png | Bin 0 -> 68147 bytes .../wwwroot/assets/img/favicon.png | Bin 839 -> 64657 bytes .../wwwroot/assets/img/hero-bg-pattern.svg | 8 + .../wwwroot/assets/js/hub-payment.js | 19 + src/webapp/Angor.Client/wwwroot/index.html | 22 +- 13 files changed, 1480 insertions(+), 304 deletions(-) create mode 100644 src/webapp/Angor.Client/Shared/HubPaymentHeader.razor create mode 100644 src/webapp/Angor.Client/wwwroot/assets/css/hub-invest-controls.css create mode 100644 src/webapp/Angor.Client/wwwroot/assets/fonts/proxima-nova/proximanova_bold.otf create mode 100644 src/webapp/Angor.Client/wwwroot/assets/fonts/proxima-nova/proximanova_light.otf create mode 100644 src/webapp/Angor.Client/wwwroot/assets/img/app-icon.png create mode 100644 src/webapp/Angor.Client/wwwroot/assets/img/hero-bg-pattern.svg create mode 100644 src/webapp/Angor.Client/wwwroot/assets/js/hub-payment.js diff --git a/src/webapp/Angor.Client/Pages/InvestView.razor b/src/webapp/Angor.Client/Pages/InvestView.razor index 712ffc549..bd1a400b1 100644 --- a/src/webapp/Angor.Client/Pages/InvestView.razor +++ b/src/webapp/Angor.Client/Pages/InvestView.razor @@ -49,28 +49,87 @@ - -
- - Angor - Angor Invest - - - @network.Name - - - Settings - - -
+ + + +@if (showConnectionModal && connectionSettings != null) +{ + +} + @if (loadingProject) { -
-
-

Loading project...

+
+
+

Loading your project

+

Preparing your payment details...

- Taking too long? Check your relay and indexer settings. + Taking too long? Check your .

return; @@ -84,8 +143,8 @@ @(loadError ?? "The project was not found.")
return; @@ -102,56 +161,20 @@ return; } -
+
- -
- @if (!string.IsNullOrEmpty(project.Metadata?.Banner)) - { - - } -
-
- @if (!string.IsNullOrEmpty(project.Metadata?.Picture)) - { - - } -
-

@(project.Metadata?.Name ?? project.ProjectInfo.ProjectIdentifier)

- @if (!string.IsNullOrEmpty(project.Metadata?.About)) - { -

@TruncateAbout(project.Metadata.About)

- } - - View full project details on angor.io - - -
+
+
+
+ Back + @(project.Metadata?.Name ?? project.ProjectInfo.ProjectIdentifier)
- - -
-
- Raised - @fundingProgressPercent% -
-
-
-
-
- - @Money.Satoshis(totalRaisedSats).ToUnit(MoneyUnit.BTC) - of @Money.Satoshis(project.ProjectInfo.TargetAmount).ToUnit(MoneyUnit.BTC) @network.CoinTicker - - @totalInvestors investors -
+
+
+ Total Raised @Money.Satoshis(totalRaisedSats).ToUnit(MoneyUnit.BTC) @network.CoinTicker + Progress @fundingProgressPercent%
- -
- Starts: @project.ProjectInfo.StartDate.ToString("dd MMM yyyy") - Expires: @project.ProjectInfo.ExpiryDate.ToString("dd MMM yyyy") - Stages: @((project.ProjectInfo.AllowDynamicStages ? SelectedPattern?.StageCount : project.ProjectInfo.Stages?.Count) ?? 0) - Penalty: @project.ProjectInfo.PenaltyDays days +
@@ -162,7 +185,7 @@
-

Investment Confirmed

+

@PaymentNoun Confirmed

Your investment was published to the Bitcoin network. To manage or recover your funds later, import your recovery phrase into the Angor desktop app. @@ -243,41 +266,50 @@ } else { -

+
+ @if (project.ProjectInfo.ProjectType != ProjectType.Subscribe) + { +
Target Amount@Money.Satoshis(project.ProjectInfo.TargetAmount).ToUnit(MoneyUnit.BTC) @network.CoinTicker
+ } + @if (!project.ProjectInfo.AllowDynamicStages) + { +
Total Raised@Money.Satoshis(totalRaisedSats).ToUnit(MoneyUnit.BTC) @network.CoinTicker
+
Progress@fundingProgressPercent%
+ } +
+
-
-
-
- -
Investment Amount
+
+
+
+ ₿ +

@PaymentNoun Amount

-
-
- -
- +
+ +
+ - @network.CoinTicker + @network.CoinTicker
- Minimum investment: 0.001 @network.CoinTicker +

Minimum investment: 0.001 @network.CoinTicker

-
+
@foreach (var preset in AmountPresets) { }
@@ -308,88 +340,138 @@
}
-
-
- - @if (ShowPatternSelector && AvailablePatterns?.Any() == true) { -
-
-
-
Funding Pattern
+
+ @if (handoffPlanNeedsSelection) + { +

The selected plan is not offered by this project. Choose an available installment count and frequency below.

+ } +
+ @InstallmentPrompt +
+ @foreach (var count in AvailablePatterns.Select(p => p.StageCount).Distinct().OrderBy(count => count)) + { + + }
-
-

Choose a funding pattern for your investment:

-
- @foreach (var pattern in AvailablePatterns) +
+ @if (!HasSinglePaymentFrequency) + { +
+ Frequency +
+ @foreach (var frequency in AvailablePatterns.Where(p => p.StageCount == SelectedPattern?.StageCount).Select(p => p.Frequency).Distinct()) + { + + } +
+
+ } + @if (AvailablePatterns.Count(p => p.StageCount == SelectedPattern?.StageCount && p.Frequency == SelectedPattern?.Frequency) > 1) + { +
+ Plan +
+ @foreach (var pattern in AvailablePatterns.Where(p => p.StageCount == SelectedPattern?.StageCount && p.Frequency == SelectedPattern?.Frequency)) { - + }
-
+ } + @if (SelectedPattern != null) + { +

@SelectedPattern.Name — @SelectedPattern.Description

+ }
} +
+
- -
-
-
-
Release Schedule
-
-
-

Your investment will be released in stages:

- @if (StagesBreakdown?.Any() == true) +
+

@(project.ProjectInfo.AllowDynamicStages ? "Payment Schedule" : "Release Schedule")

+

Your @(project.ProjectInfo.AllowDynamicStages ? "payments" : "investment will be released in stages"):

+
+ @if (StagesBreakdown?.Any() == true) + { + int stageIndex = 0; + @foreach (var stage in StagesBreakdown) { - int stageIndex = 0; - @foreach (var stage in StagesBreakdown) - { - stageIndex++; -
-
-
- Stage @stageIndex - - @(project?.ProjectInfo?.Stages?.ElementAtOrDefault(stageIndex - 1)?.AmountToRelease.ToString("F1"))% - -
-
- @stage.StageDateTime.FormatDate() - @stage.AmountBtc.ToString("0.00000000") @network.CoinTicker -
-
+ stageIndex++; +
+
+ @(project.ProjectInfo.AllowDynamicStages ? "Payment" : "Stage") @stageIndex + @stage.StageDateTime.FormatDate()
- } - } - else - { -

Enter an amount to see the stage breakdown.

+
+ @if (!project.ProjectInfo.AllowDynamicStages) + { + @(project.ProjectInfo.Stages?.ElementAtOrDefault(stageIndex - 1)?.AmountToRelease.ToString("F1"))% + } + @stage.AmountBtc.ToString("0.00000000") @network.CoinTicker +
+
} -
+ } + else + { +

Enter an amount to see the stage breakdown.

+ }
+
+

Transaction Details

+
+
Project ID
@ProjectId
+
Amount to @PaymentAction@Investment.InvestmentAmountBtc @network.CoinTicker
+
Miner FeeCalculated with invoice
+
Angor FeeIncluded in invoice total
+
+
+
+ + + + } + + + +
+ +@if (showHelpModal) +{ -
-
-
-
How It Works
+