mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-22 14:22:40 +01:00
more integration
This commit is contained in:
parent
d9426d301d
commit
35f4ea29f9
11 changed files with 241 additions and 104 deletions
|
@ -124,7 +124,6 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Folder Include="Build\" />
|
||||
<Folder Include="Views\AppsPublic\Crowdfund\Templates" />
|
||||
<Folder Include="wwwroot\vendor\clipboard.js\" />
|
||||
<Folder Include="wwwroot\vendor\highlightjs\" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -8,6 +8,11 @@ namespace BTCPayServer.Controllers
|
|||
{
|
||||
public partial class AppsController
|
||||
{
|
||||
public class CrowdfundAppUpdated
|
||||
{
|
||||
public string AppId { get; set; }
|
||||
}
|
||||
|
||||
public class CrowdfundSettings
|
||||
{
|
||||
public string Title { get; set; }
|
||||
|
@ -51,7 +56,7 @@ namespace BTCPayServer.Controllers
|
|||
TargetAmount = settings.TargetAmount,
|
||||
CustomCSSLink = settings.CustomCSSLink,
|
||||
NotificationUrl = settings.NotificationUrl,
|
||||
Tagline = settings.Tagline
|
||||
Tagline = settings.Tagline,
|
||||
};
|
||||
return View(vm);
|
||||
}
|
||||
|
@ -70,10 +75,10 @@ namespace BTCPayServer.Controllers
|
|||
Title = vm.Title,
|
||||
Enabled = vm.Enabled,
|
||||
EnforceTargetAmount = vm.EnforceTargetAmount,
|
||||
StartDate = vm.StartDate?.ToUniversalTime(),
|
||||
StartDate = vm.StartDate,
|
||||
TargetCurrency = vm.TargetCurrency,
|
||||
Description = vm.Description,
|
||||
EndDate = vm.EndDate?.ToUniversalTime(),
|
||||
EndDate = vm.EndDate,
|
||||
TargetAmount = vm.TargetAmount,
|
||||
CustomCSSLink = vm.CustomCSSLink,
|
||||
MainImageUrl = vm.MainImageUrl,
|
||||
|
@ -82,6 +87,10 @@ namespace BTCPayServer.Controllers
|
|||
Tagline = vm.Tagline
|
||||
});
|
||||
await UpdateAppSettings(app);
|
||||
_EventAggregator.Publish(new CrowdfundAppUpdated()
|
||||
{
|
||||
AppId = appId
|
||||
});
|
||||
StatusMessage = "App updated";
|
||||
return RedirectToAction(nameof(ListApps));
|
||||
}
|
||||
|
|
|
@ -24,17 +24,20 @@ namespace BTCPayServer.Controllers
|
|||
public AppsController(
|
||||
UserManager<ApplicationUser> userManager,
|
||||
ApplicationDbContextFactory contextFactory,
|
||||
EventAggregator eventAggregator,
|
||||
BTCPayNetworkProvider networkProvider,
|
||||
AppsHelper appsHelper)
|
||||
{
|
||||
_UserManager = userManager;
|
||||
_ContextFactory = contextFactory;
|
||||
_EventAggregator = eventAggregator;
|
||||
_NetworkProvider = networkProvider;
|
||||
_AppsHelper = appsHelper;
|
||||
}
|
||||
|
||||
private UserManager<ApplicationUser> _UserManager;
|
||||
private ApplicationDbContextFactory _ContextFactory;
|
||||
private readonly EventAggregator _EventAggregator;
|
||||
private BTCPayNetworkProvider _NetworkProvider;
|
||||
private AppsHelper _AppsHelper;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
|||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Filters;
|
||||
using BTCPayServer.Hubs;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Models.AppViewModels;
|
||||
using BTCPayServer.Rating;
|
||||
using BTCPayServer.Security;
|
||||
|
@ -16,6 +17,7 @@ using BTCPayServer.Services.Invoices;
|
|||
using BTCPayServer.Services.Rates;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Cors;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NBitpayClient;
|
||||
|
@ -28,16 +30,18 @@ namespace BTCPayServer.Controllers
|
|||
{
|
||||
public AppsPublicController(AppsHelper appsHelper,
|
||||
InvoiceController invoiceController,
|
||||
CrowdfundHubStreamer crowdfundHubStreamer)
|
||||
CrowdfundHubStreamer crowdfundHubStreamer, UserManager<ApplicationUser> userManager)
|
||||
{
|
||||
_AppsHelper = appsHelper;
|
||||
_InvoiceController = invoiceController;
|
||||
_CrowdfundHubStreamer = crowdfundHubStreamer;
|
||||
_UserManager = userManager;
|
||||
}
|
||||
|
||||
private AppsHelper _AppsHelper;
|
||||
private InvoiceController _InvoiceController;
|
||||
private readonly CrowdfundHubStreamer _CrowdfundHubStreamer;
|
||||
private readonly UserManager<ApplicationUser> _UserManager;
|
||||
|
||||
[HttpGet]
|
||||
[Route("/apps/{appId}/pos")]
|
||||
|
@ -86,8 +90,10 @@ namespace BTCPayServer.Controllers
|
|||
public async Task<IActionResult> ViewCrowdfund(string appId, string statusMessage)
|
||||
|
||||
{
|
||||
var app = await _AppsHelper.GetApp(appId, AppType.Crowdfund, true);
|
||||
if (app == null)
|
||||
var app = await _AppsHelper.GetApp(appId, AppType.Crowdfund, true);
|
||||
if (app == null ||
|
||||
(!app.GetSettings<CrowdfundSettings>().Enabled &&
|
||||
_AppsHelper.GetAppDataIfOwner(GetUserId(), appId, AppType.Crowdfund) == null))
|
||||
return NotFound();
|
||||
|
||||
return View(await _CrowdfundHubStreamer.GetCrowdfundInfo(appId));
|
||||
|
@ -101,7 +107,9 @@ namespace BTCPayServer.Controllers
|
|||
public async Task<IActionResult> ContributeToCrowdfund(string appId, ContributeToCrowdfund request)
|
||||
{
|
||||
var app = await _AppsHelper.GetApp(appId, AppType.Crowdfund, true);
|
||||
if (app == null)
|
||||
if (app == null ||
|
||||
(!app.GetSettings<CrowdfundSettings>().Enabled &&
|
||||
_AppsHelper.GetAppDataIfOwner(GetUserId(), appId, AppType.Crowdfund) == null))
|
||||
return NotFound();
|
||||
var settings = app.GetSettings<CrowdfundSettings>();
|
||||
var store = await _AppsHelper.GetStore(app);
|
||||
|
@ -191,6 +199,12 @@ namespace BTCPayServer.Controllers
|
|||
}, store, HttpContext.Request.GetAbsoluteRoot());
|
||||
return RedirectToAction(nameof(InvoiceController.Checkout), "Invoice", new { invoiceId = invoice.Data.Id });
|
||||
}
|
||||
|
||||
|
||||
private string GetUserId()
|
||||
{
|
||||
return _UserManager.GetUserId(User);
|
||||
}
|
||||
}
|
||||
|
||||
public class AppsHelper
|
||||
|
@ -310,5 +324,6 @@ namespace BTCPayServer.Controllers
|
|||
return app;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace BTCPayServer.Hubs
|
|||
var token = new CancellationTokenSource();
|
||||
_CacheTokens.Add(key, token);
|
||||
entry.AddExpirationToken(new CancellationChangeToken(token.Token));
|
||||
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(20);
|
||||
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(5);
|
||||
|
||||
var app = await _AppsHelper.GetApp(appId, AppType.Crowdfund, true);
|
||||
var result = await GetInfo(app, _InvoiceRepository, _RateFetcher,
|
||||
|
@ -110,6 +110,10 @@ namespace BTCPayServer.Hubs
|
|||
{
|
||||
|
||||
_EventAggregator.Subscribe<InvoiceEvent>(Subscription);
|
||||
_EventAggregator.Subscribe<AppsController.CrowdfundAppUpdated>(updated =>
|
||||
{
|
||||
InvalidateCacheForApp(updated.AppId);
|
||||
});
|
||||
}
|
||||
|
||||
private string GetCacheKey(string appId)
|
||||
|
@ -127,17 +131,22 @@ namespace BTCPayServer.Hubs
|
|||
switch (invoiceEvent.Name)
|
||||
{
|
||||
case InvoiceEvent.ReceivedPayment:
|
||||
_HubContext.Clients.Group(appId).SendCoreAsync("PaymentReceived", new object[]{ invoiceEvent.Invoice.AmountPaid } );
|
||||
_HubContext.Clients.Group(appId).SendCoreAsync("PaymentReceived", new object[]{ invoiceEvent.Invoice.CryptoInfo.First().Paid } );
|
||||
break;
|
||||
case InvoiceEvent.Completed:
|
||||
if (_CacheTokens.ContainsKey(appId))
|
||||
{
|
||||
_CacheTokens[appId].Cancel();
|
||||
}
|
||||
_HubContext.Clients.Group(appId).SendCoreAsync("InfoUpdated", new object[]{} );
|
||||
InvalidateCacheForApp(appId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void InvalidateCacheForApp(string appId)
|
||||
{
|
||||
if (_CacheTokens.ContainsKey(appId))
|
||||
{
|
||||
_CacheTokens[appId].Cancel();
|
||||
}
|
||||
_HubContext.Clients.Group(appId).SendCoreAsync("InfoUpdated", new object[]{} );
|
||||
}
|
||||
|
||||
private static async Task<decimal> GetCurrentContributionAmount(InvoiceEntity[] invoices, string primaryCurrency,
|
||||
RateFetcher rateFetcher, RateRules rateRules)
|
||||
|
@ -170,19 +179,25 @@ namespace BTCPayServer.Hubs
|
|||
return result;
|
||||
|
||||
}
|
||||
|
||||
public static async Task<ViewCrowdfundViewModel> GetInfo(AppData appData, InvoiceRepository invoiceRepository,
|
||||
|
||||
private static async Task<ViewCrowdfundViewModel> GetInfo(AppData appData, InvoiceRepository invoiceRepository,
|
||||
RateFetcher rateFetcher, BTCPayNetworkProvider btcPayNetworkProvider, string statusMessage= null)
|
||||
{
|
||||
var settings = appData.GetSettings<AppsController.CrowdfundSettings>();
|
||||
var invoices = await GetPaidInvoicesForApp(appData, invoiceRepository);
|
||||
var invoices = await GetInvoicesForApp(appData, invoiceRepository);
|
||||
|
||||
|
||||
var rateRules = appData.StoreData.GetStoreBlob().GetRateRules(btcPayNetworkProvider);
|
||||
var currentAmount = await GetCurrentContributionAmount(
|
||||
invoices,
|
||||
invoices.Where(entity => entity.Status == InvoiceStatus.Complete).ToArray(),
|
||||
settings.TargetCurrency, rateFetcher, rateRules);
|
||||
var paidInvoices = invoices.Length;
|
||||
var active = (settings.StartDate == null || DateTime.UtcNow >= settings.StartDate) &&
|
||||
(settings.EndDate == null || DateTime.UtcNow <= settings.EndDate) &&
|
||||
var currentPendingAmount = await GetCurrentContributionAmount(
|
||||
invoices.Where(entity => entity.Status != InvoiceStatus.Complete).ToArray(),
|
||||
settings.TargetCurrency, rateFetcher, rateRules);
|
||||
|
||||
|
||||
var active = (settings.StartDate == null || DateTime.Now >= settings.StartDate) &&
|
||||
(settings.EndDate == null || DateTime.Now <= settings.EndDate) &&
|
||||
(!settings.EnforceTargetAmount || settings.TargetAmount > currentAmount);
|
||||
|
||||
return new ViewCrowdfundViewModel()
|
||||
|
@ -203,23 +218,29 @@ namespace BTCPayServer.Hubs
|
|||
StatusMessage = statusMessage,
|
||||
Info = new ViewCrowdfundViewModel.CrowdfundInfo()
|
||||
{
|
||||
TotalContributors = paidInvoices,
|
||||
TotalContributors = invoices.Length,
|
||||
CurrentPendingAmount = currentPendingAmount,
|
||||
CurrentAmount = currentAmount,
|
||||
Active = active,
|
||||
DaysLeft = settings.EndDate.HasValue? (settings.EndDate - DateTime.UtcNow).Value.Days: (int?) null,
|
||||
DaysLeftToStart = settings.StartDate.HasValue? (settings.StartDate - DateTime.UtcNow).Value.Days: (int?) null,
|
||||
ShowProgress =active && settings.TargetAmount.HasValue,
|
||||
ProgressPercentage = currentAmount/ settings.TargetAmount * 100
|
||||
ShowProgress = settings.TargetAmount.HasValue,
|
||||
ProgressPercentage = (currentAmount/ settings.TargetAmount) * 100,
|
||||
PendingProgressPercentage = ( currentPendingAmount/ settings.TargetAmount) * 100
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static async Task<InvoiceEntity[]> GetPaidInvoicesForApp(AppData appData, InvoiceRepository invoiceRepository)
|
||||
private static async Task<InvoiceEntity[]> GetInvoicesForApp(AppData appData, InvoiceRepository invoiceRepository)
|
||||
{
|
||||
return await invoiceRepository.GetInvoices(new InvoiceQuery()
|
||||
{
|
||||
OrderId = appData.Id,
|
||||
Status = new string[]{ InvoiceState.ToString(InvoiceStatus.Complete)}
|
||||
OrderId = $"{CrowdfundInvoiceOrderIdPrefix}{appData.Id}",
|
||||
Status = new string[]{
|
||||
InvoiceState.ToString(InvoiceStatus.New),
|
||||
InvoiceState.ToString(InvoiceStatus.Paid),
|
||||
InvoiceState.ToString(InvoiceStatus.Confirmed),
|
||||
InvoiceState.ToString(InvoiceStatus.Complete)}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ namespace BTCPayServer.Models.AppViewModels
|
|||
[MaxLength(30)]
|
||||
public string Title { get; set; }
|
||||
|
||||
[MaxLength(50)]
|
||||
public string Tagline { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Description { get; set; }
|
||||
public string MainImageUrl { get; set; }
|
||||
|
@ -16,7 +19,7 @@ namespace BTCPayServer.Models.AppViewModels
|
|||
public string NotificationUrl { get; set; }
|
||||
|
||||
[Required]
|
||||
public bool Enabled { get; set; }
|
||||
public bool Enabled { get; set; } = false;
|
||||
|
||||
public DateTime? StartDate { get; set; }
|
||||
public DateTime? EndDate { get; set; }
|
||||
|
@ -37,7 +40,6 @@ namespace BTCPayServer.Models.AppViewModels
|
|||
[Display(Name = "Custom bootstrap CSS file")]
|
||||
public string CustomCSSLink { get; set; }
|
||||
|
||||
public string Tagline { get; set; }
|
||||
public string EmbeddedCSS { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ namespace BTCPayServer.Models.AppViewModels
|
|||
public decimal? ProgressPercentage { get; set; }
|
||||
public int? DaysLeft{ get; set; }
|
||||
public int? DaysLeftToStart{ get; set; }
|
||||
public decimal CurrentPendingAmount { get; set; }
|
||||
public decimal? PendingProgressPercentage { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,97 +2,135 @@
|
|||
<div class="row h-100 w-100 py-sm-0 py-md-4 mx-0">
|
||||
<div class="card w-100 p-0 mx-0">
|
||||
<img class="card-img-top" :src="srvModel.mainImageUrl" v-if="srvModel.mainImageUrl">
|
||||
<div class="progress rounded-0 striped" style="min-height: 30px" v-if="srvModel.info.showProgres">
|
||||
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" :aria-valuenow="srvModel.info.progressPercentage" aria-valuemin="0" aria-valuemax="100">
|
||||
<div class="progress rounded-0" style="min-height: 30px" v-if="srvModel.info.showProgress">
|
||||
<div class="progress-bar p" role="progressbar" :aria-valuenow="srvModel.info.progressPercentage" aria-valuemin="0" aria-valuemax="100">
|
||||
<template v-if="srvModel.info.progressPercentage > 0">
|
||||
{{srvModel.info.progressPercentage}} %
|
||||
{{srvModel.info.progressPercentage}} % Funded
|
||||
</template>
|
||||
</div>
|
||||
<div class="progress-bar bg-warning" role="progressbar" :aria-valuenow="srvModel.info.progressPercentage" aria-valuemin="0" aria-valuemax="100">
|
||||
<template v-if="srvModel.info.progressPercentage > 0">
|
||||
{{srvModel.info.pendingProgressPercentage}} % Pending
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="card-title row">
|
||||
<div class="col-md-9 col-sm-12">
|
||||
<div class="col-md-6 col-sm-12">
|
||||
|
||||
<h1 >
|
||||
<span class="h1" >
|
||||
{{srvModel.title}}
|
||||
<h2 class="text-muted" v-if="srvModel.tagline">{{srvModel.tagline}}</h2>
|
||||
<small v-if="srvModel.info.daysLeftToStart && srvModel.info.daysLeftToStart > 0">
|
||||
{{ srvModel.info.daysLeftToStart }} days left to start
|
||||
</small>
|
||||
</h1>
|
||||
<span class="h6 text-muted" v-if="!started && srvModel.startDate">
|
||||
Starts {{startDateRelativeTime}}
|
||||
</span>
|
||||
<span class="h6 " v-else-if="started && !ended && srvModel.endDate">
|
||||
Ends {{endDateRelativeTime}}
|
||||
</span>
|
||||
<span class="h6 text-muted" v-else-if="started && !ended && srvModel.endDate">
|
||||
Currently Active!
|
||||
</span>
|
||||
|
||||
</span>
|
||||
|
||||
<h2 class="text-muted" v-if="srvModel.tagline">{{srvModel.tagline}}</h2>
|
||||
<button v-if="srvModel.info.active" class="btn btn-lg btn-primary w-100" v-on:click="contributeModalOpen = true">Contribute</button>
|
||||
|
||||
|
||||
</div>
|
||||
<ul class="list-group list-group-flush col-md-3 col-sm-12">
|
||||
<li class="list-group-item" v-if="startDate">
|
||||
<template>{{started}} {{ended}}</template>
|
||||
</li>
|
||||
<li class="list-group-item" v-if="startDate">
|
||||
<template>Starts {{startDate}}</template>
|
||||
<ul class="list-group list-group-flush col-md-6 col-sm-12">
|
||||
<li class="list-group-item border-0">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<span class="h5">{{srvModel.info.currentAmount + srvModel.info.currentPendingAmount }} {{targetCurrency}} </span>
|
||||
<span>raised by {{srvModel.info.totalContributors}} contributors </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progress w-100" v-if="srvModel.info.showProgress">
|
||||
<div class="progress-bar" role="progressbar"
|
||||
:aria-valuenow="srvModel.info.progressPercentage"
|
||||
v-bind:style="{ width: srvModel.info.progressPercentage + '%' }"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100">
|
||||
<template v-if="srvModel.info.progressPercentage > 0">
|
||||
{{srvModel.info.progressPercentage}}% Funded
|
||||
</template>
|
||||
</div>
|
||||
<div class="progress-bar bg-warning" role="progressbar"
|
||||
:aria-valuenow="srvModel.info.pendingProgressPercentage"
|
||||
v-bind:style="{ width: srvModel.info.pendingProgressPercentage + '%' }"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100">
|
||||
<template v-if="srvModel.info.pendingProgressPercentage > 0">
|
||||
{{srvModel.info.pendingProgressPercentage}}% Pending
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<template v-if="endDate">Ends {{endDate}}</template>
|
||||
<template v-else>No specific end date</template>
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<template v-if="srvModel.targetAmount">{{srvModel.targetAmount}} {{srvModel.targetCurrency}} Goal</template>
|
||||
<template v-else>No specific target goal</template>
|
||||
<span v-if="srvModel.targetAmount" class="h5">{{srvModel.targetAmount}} {{targetCurrency}}</span>
|
||||
|
||||
<span v-if="srvModel.enforceTargetAmount">Hardcap Goal <small>- No contributions allowed after the goal has been reached</small></span>
|
||||
<span v-else>Softcap Goal <small>- Contributions allowed after goal is reached</small></span>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
<li class="list-group-item">
|
||||
<template v-if="srvModel.enforceTargetAmount">Hardcap Goal</template>
|
||||
<template v-else>Softcap Goal</template>
|
||||
<template v-if="startDate">
|
||||
<template v-if="started">
|
||||
Started {{startDate}}
|
||||
</template>
|
||||
<template v-else-if="!started">
|
||||
Starts {{startDate}}
|
||||
</template>
|
||||
&
|
||||
</template>
|
||||
<template class="list-group-item" v-if="endDate">
|
||||
<template v-if="!ended">
|
||||
Ends {{endDate}}
|
||||
</template>
|
||||
<template v-else-if="ended">
|
||||
Ended {{endDate}}
|
||||
</template>
|
||||
</template>
|
||||
<template class="list-group-item" v-else-if="!endDate">
|
||||
No specific end date
|
||||
</template>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div class="card-deck mb-4" v-if="srvModel.info.active">
|
||||
<div class="card shadow">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-center">{{srvModel.info.totalContributors}}</h5>
|
||||
<h6 class="card-text text-center"> Contributors</h6>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-sm-12">
|
||||
<div class="card-text" v-html="srvModel.description"></div>
|
||||
</div>
|
||||
<div class="card shadow">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-center">{{srvModel.info.currentAmount}} {{srvModel.info.targetCurrency}}</h5>
|
||||
<h6 class="card-text text-center"> Raised</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow" v-if="srvModel.info.daysLeft && srvModel.info.daysLeft >0">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-center">Ends {{endDateRelativeTime}}</h5>
|
||||
</div>
|
||||
<div class="col-md-4 col-sm-12">
|
||||
<contribute :target-currency="srvModel.targetCurrency" :active="srvModel.info.active"></contribute>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card-text" v-html="srvModel.description"></div>
|
||||
<template v-if="srvModel.info.active"></template>
|
||||
<hr/>
|
||||
<h3>Contribute</h3>
|
||||
|
||||
<form v-on:submit="onContributeFormSubmit">
|
||||
|
||||
<div class="form-group">
|
||||
<label ></label>
|
||||
<input type="email" class="form-control" v-model="contributionForm.email"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label ></label>
|
||||
<div class="input-group mb-3">
|
||||
<input type="number" step="any" class="form-control" v-model="contributionForm.amount"/>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">{{srvModel.targetCurrency}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Contribute</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<b-modal title="Contribute" v-model="contributeModalOpen" v-on:ok="submitModalContribute" :hide-header-close="true">
|
||||
|
||||
<contribute :target-currency="srvModel.targetCurrency" :active="srvModel.info.active" ref="modalContribute" :in-modal="true"></contribute>
|
||||
<template slot="modal-ok">
|
||||
Submit
|
||||
</template>
|
||||
</b-modal>
|
||||
<b-modal title="Thank You!" v-model="thankYouModalOpen" :ok-only="true">
|
||||
Thank you for your contribution.
|
||||
</b-modal>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
"outputFileName": "wwwroot/bundles/crowdfund-bundle.min.js",
|
||||
"inputFiles": [
|
||||
"wwwroot/vendor/vuejs/vue.min.js",
|
||||
"wwwroot/vendor/vue-toasted/vue-toasted.min.js",
|
||||
"wwwroot/vendor/babel-polyfill/polyfill.min.js",
|
||||
"wwwroot/vendor/bootstrap-vue/bootstrap-vue.js",
|
||||
"wwwroot/vendor/signalr/signalr.js",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
var app = null;
|
||||
var eventAggregator = new Vue();
|
||||
window.onload = function (ev) {
|
||||
Vue.use(Toasted);
|
||||
app = new Vue({
|
||||
el: '#app',
|
||||
data: function(){
|
||||
|
@ -13,10 +14,15 @@ window.onload = function (ev) {
|
|||
endDateRelativeTime: "",
|
||||
started: false,
|
||||
ended: false,
|
||||
contributionForm: { email: "", amount: 0}
|
||||
contributeModalOpen: false,
|
||||
thankYouModalOpen: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
targetCurrency: function(){
|
||||
return this.srvModel.targetCurrency.toUpperCase();
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
updateComputed: function () {
|
||||
if (this.srvModel.endDate) {
|
||||
|
@ -25,7 +31,7 @@ window.onload = function (ev) {
|
|||
this.endDateRelativeTime = endDateM.fromNow();
|
||||
this.ended = endDateM.isBefore(moment());
|
||||
}else{
|
||||
this.ended = true;
|
||||
this.ended = false;
|
||||
}
|
||||
|
||||
if (this.srvModel.startDate) {
|
||||
|
@ -38,22 +44,27 @@ window.onload = function (ev) {
|
|||
}
|
||||
setTimeout(this.updateComputed, 1000);
|
||||
},
|
||||
onContributeFormSubmit: function(e){
|
||||
if(e){
|
||||
e.preventDefault();
|
||||
}
|
||||
eventAggregator.$emit("contribute", this.contributionForm);
|
||||
submitModalContribute: function(e){
|
||||
debugger;
|
||||
this.$refs.modalContribute.onContributeFormSubmit(e);
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
hubListener.connect();
|
||||
var self = this;
|
||||
eventAggregator.$on("invoice-created", function (invoiceId) {
|
||||
btcpay.setApiUrlPrefix(window.location.origin);
|
||||
btcpay.showInvoice(invoiceId);
|
||||
btcpay.showFrame();
|
||||
});
|
||||
|
||||
self.contributeModalOpen = false;
|
||||
});
|
||||
btcpay.onModalWillLeave = function(){
|
||||
self.thankYouModalOpen = true;
|
||||
};
|
||||
eventAggregator.$on("payment-received", function (amount) {
|
||||
console.warn("AAAAAA", amount);
|
||||
Vue.toasted.show('New payment of ' + amount+ " BTC registered");
|
||||
});
|
||||
eventAggregator.$on("info-updated", function (model) {
|
||||
this.srvModel = model;
|
||||
|
|
|
@ -1,7 +1,43 @@
|
|||
Vue.component('contribute', {
|
||||
props: ["targetCurrency", "active", "inModal"],
|
||||
data: function () {
|
||||
return {
|
||||
email: "",
|
||||
amount: 0,
|
||||
choiceKey: ""
|
||||
}
|
||||
},
|
||||
template: ''
|
||||
methods: {
|
||||
onContributeFormSubmit: function (e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
if(!this.active){
|
||||
return;
|
||||
}
|
||||
eventAggregator.$emit("contribute", {email: this.email, amount: this.amount, choiceKey: this.choiceKey});
|
||||
}
|
||||
},
|
||||
|
||||
template: "<div>" +
|
||||
"<h3 v-if='!inModal'>Contribute</h3>" +
|
||||
"" +
|
||||
" <form v-on:submit=\"onContributeFormSubmit\">" +
|
||||
"" +
|
||||
" <div class=\"form-group\">" +
|
||||
" <label ></label>" +
|
||||
" <input type=\"email\" class=\"form-control\" v-model=\"email\" placeholder='Email'/>" +
|
||||
" </div>" +
|
||||
" <div class=\"form-group\">" +
|
||||
" <label ></label>" +
|
||||
" <div class=\"input-group mb-3\">" +
|
||||
" <input type=\"number\" step=\"any\" class=\"form-control\" v-model=\"amount\" placeholder='Contribution Amount'/>" +
|
||||
" <div class=\"input-group-append\">" +
|
||||
" <span class=\"input-group-text\">{{targetCurrency}}</span>" +
|
||||
" </div>" +
|
||||
" </div>" +
|
||||
" </div>" +
|
||||
" <button type=\"submit\" class=\"btn btn-primary\" :disabled='!active' v-if='!inModal'>Contribute</button>" +
|
||||
" </form>" +
|
||||
"</div>"
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue