Browse Source

Implementation of payment design

pull/79/head
berkansasmaz 5 years ago
parent
commit
c1a2cb73e4
No known key found for this signature in database GPG Key ID: 884D815C3F32BE00
  1. 26
      modules/payment/src/Payment.Web/Pages/Payment/PostCheckout.cshtml.cs
  2. 24
      modules/payment/src/Payment.Web/Pages/Payment/PreCheckout.cshtml.cs
  3. 34
      src/EventHub.Web/EventHubWebModule.cs
  4. 2
      src/EventHub.Web/Pages/Empty.cshtml
  5. 56
      src/EventHub.Web/Pages/Organizations/Components/_upgradeOrExtendOrganizationSection.cshtml
  6. 43
      src/EventHub.Web/Pages/Organizations/Profile.cshtml
  7. 29
      src/EventHub.Web/Pages/Organizations/Profile.js
  8. 77
      src/EventHub.Web/Pages/Payment/CustomPostCheckout.cshtml.cs
  9. 23
      src/EventHub.Web/Pages/Payment/PostCheckout.cshtml
  10. 115
      src/EventHub.Web/Pages/Payment/PreCheckout.cshtml
  11. 231
      src/EventHub.Web/Pages/Pricing.cshtml
  12. 1
      src/EventHub.Web/wwwroot/assets/success.svg

26
modules/payment/src/Payment.Web/Pages/Payment/PostCheckout.cshtml.cs

@ -16,42 +16,42 @@ namespace Payment.Web.Pages.Payment
public string GoBackLink { get; set; }
private readonly IPaymentRequestAppService _paymentRequestAppService;
private readonly PaymentWebOptions _paymentWebOptions;
private readonly IPaymentUrlBuilder _paymentUrlBuilder;
protected IPaymentRequestAppService PaymentRequestAppService { get; }
protected PaymentWebOptions PaymentWebOptions { get; }
protected IPaymentUrlBuilder PaymentUrlBuilder { get; }
public PostCheckoutPageModel(
IPaymentRequestAppService appService,
IOptions<PaymentWebOptions> paymentWebOptions,
IPaymentUrlBuilder paymentUrlBuilder)
{
_paymentRequestAppService = appService;
_paymentWebOptions = paymentWebOptions.Value;
_paymentUrlBuilder = paymentUrlBuilder;
PaymentRequestAppService = appService;
PaymentWebOptions = paymentWebOptions.Value;
PaymentUrlBuilder = paymentUrlBuilder;
}
public async Task<IActionResult> OnGetAsync()
public virtual async Task<IActionResult> OnGetAsync()
{
if (Token.IsNullOrWhiteSpace())
{
return BadRequest();
}
PaymentRequest = await _paymentRequestAppService.CompleteAsync(Token);
PaymentRequest = await PaymentRequestAppService.CompleteAsync(Token);
GoBackLink = _paymentUrlBuilder.BuildCheckoutUrl(PaymentRequest.Id).AbsoluteUri;
GoBackLink = PaymentUrlBuilder.BuildCheckoutUrl(PaymentRequest.Id).AbsoluteUri;
if (PaymentRequest.State == PaymentRequestState.Completed
&& !_paymentWebOptions.PaymentSuccessfulCallbackUrl.IsNullOrWhiteSpace())
&& !PaymentWebOptions.PaymentSuccessfulCallbackUrl.IsNullOrWhiteSpace())
{
var callbackUrl = _paymentWebOptions.PaymentSuccessfulCallbackUrl + "?paymentRequestId=" + PaymentRequest.Id;
var callbackUrl = PaymentWebOptions.PaymentSuccessfulCallbackUrl + "?paymentRequestId=" + PaymentRequest.Id;
Response.Redirect(callbackUrl);
}
if (PaymentRequest.State == PaymentRequestState.Failed
&& !_paymentWebOptions.PaymentFailureCallbackUrl.IsNullOrWhiteSpace())
&& !PaymentWebOptions.PaymentFailureCallbackUrl.IsNullOrWhiteSpace())
{
var callbackUrl = _paymentWebOptions.PaymentFailureCallbackUrl + "?paymentRequestId=" + PaymentRequest.Id;
var callbackUrl = PaymentWebOptions.PaymentFailureCallbackUrl + "?paymentRequestId=" + PaymentRequest.Id;
Response.Redirect(callbackUrl);
}

24
modules/payment/src/Payment.Web/Pages/Payment/PreCheckout.cshtml.cs

@ -14,36 +14,36 @@ namespace Payment.Web.Pages.Payment
public PaymentRequestDto PaymentRequest { get; set; }
private readonly IPaymentRequestAppService _paymentRequestAppService;
private readonly IPaymentUrlBuilder _paymentUrlBuilder;
protected IPaymentRequestAppService PaymentRequestAppService { get; }
protected IPaymentUrlBuilder PaymentUrlBuilder { get; }
public PreCheckoutPageModel(
IPaymentRequestAppService paymentRequestAppService,
IPaymentUrlBuilder paymentUrlBuilder)
{
_paymentRequestAppService = paymentRequestAppService;
_paymentUrlBuilder = paymentUrlBuilder;
PaymentRequestAppService = paymentRequestAppService;
PaymentUrlBuilder = paymentUrlBuilder;
}
public async Task<IActionResult> OnGetAsync()
public virtual async Task<IActionResult> OnGetAsync()
{
PaymentRequest = await _paymentRequestAppService.GetAsync(PaymentRequestId);
PaymentRequest = await PaymentRequestAppService.GetAsync(PaymentRequestId);
return Page();
}
public async Task OnPostAsync()
public virtual async Task OnPostAsync()
{
PaymentRequest = await _paymentRequestAppService.GetAsync(PaymentRequestId);
PaymentRequest = await PaymentRequestAppService.GetAsync(PaymentRequestId);
var result = await _paymentRequestAppService.StartPaymentAsync(new StartPaymentDto
var result = await PaymentRequestAppService.StartPaymentAsync(new StartPaymentDto
{
PaymentRequestId = PaymentRequest.Id,
ReturnUrl = _paymentUrlBuilder.BuildReturnUrl(PaymentRequestId).AbsoluteUri,
CancelUrl = _paymentUrlBuilder.BuildCheckoutUrl(PaymentRequestId).AbsoluteUri
ReturnUrl = PaymentUrlBuilder.BuildReturnUrl(PaymentRequestId).AbsoluteUri,
CancelUrl = PaymentUrlBuilder.BuildCheckoutUrl(PaymentRequestId).AbsoluteUri
});
Response.Redirect(result.CheckoutLink);
}
}
}
}

34
src/EventHub.Web/EventHubWebModule.cs

@ -89,23 +89,7 @@ namespace EventHub.Web
ConfigureRazorPageOptions();
ConfigurePremiumPlanInfo(context, configuration);
}
private void ConfigurePremiumPlanInfo(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddOptions<PremiumPlanInfoOptions>()
.Bind(configuration.GetSection(PremiumPlanInfoOptions.OrganizationPlanInfo))
.ValidateDataAnnotations()
.Validate(config =>
{
if (config.IsActive)
{
return config.OnePremiumPeriodAsMonth > config.CanBeExtendedAfterHowManyMonths;
}
return true;
}, "OnePremiumPeriodAsMonth must be greater than CanBeExtendedAfterHowManyMonths.");
}
private void ConfigureBundles()
{
Configure<AbpBundlingOptions>(options =>
@ -250,6 +234,22 @@ namespace EventHub.Web
.PersistKeysToStackExchangeRedis(redis, "EventHub-Protection-Keys");
}
private void ConfigurePremiumPlanInfo(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddOptions<PremiumPlanInfoOptions>()
.Bind(configuration.GetSection(PremiumPlanInfoOptions.OrganizationPlanInfo))
.ValidateDataAnnotations()
.Validate(config =>
{
if (config.IsActive)
{
return config.OnePremiumPeriodAsMonth > config.CanBeExtendedAfterHowManyMonths;
}
return true;
}, "OnePremiumPeriodAsMonth must be greater than CanBeExtendedAfterHowManyMonths.");
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();

2
src/EventHub.Web/Pages/Empty.cshtml

@ -1,7 +1,7 @@
@page "/test"
@using EventHub.Web.Pages
@model EventHub.Web.Pages.Empty
@* TODO(berkansasmaz): Delete this page *@
<main class="static-page container mt-5">
<h1 class="text-center mb-3">Create an Event</h1>
<p class="text-center mb-5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ut nulla consequat, tempus sapien in,

56
src/EventHub.Web/Pages/Organizations/Components/_upgradeOrExtendOrganizationSection.cshtml

@ -0,0 +1,56 @@
@using EventHub.Web.PaymentRequests
@using Microsoft.Extensions.Options
@model EventHub.Organizations.OrganizationProfileDto
@inject IOptionsSnapshot<PremiumPlanInfoOptions> PremiumPlanInfoOptionsSnapshot
<abp-container class="mt-4">
<abp-row>
@if (Model.IsPremium && PremiumPlanInfoOptionsSnapshot.Value.IsActive && PremiumPlanInfoOptionsSnapshot.Value.IsExtendable && Model.PremiumEndDate!.Value.IsBetween(DateTime.Now, DateTime.Now.AddMonths(PremiumPlanInfoOptionsSnapshot.Value.OnePremiumPeriodAsMonth - PremiumPlanInfoOptionsSnapshot.Value.CanBeExtendedAfterHowManyMonths)))
{
<span class="mb-2 ms-5 text-center strong">Premium end date: @Model.PremiumEndDate!.Value.ToShortDateString()</span>
}
<abp-column>
<a href="/organization/edit/@Model.Name" class="btn btn-success text-white">Edit</a>
</abp-column>
<abp-column size="_9">
@if (PremiumPlanInfoOptionsSnapshot.Value.IsActive)
{
@if (Model.IsPremium)
{
@if (PremiumPlanInfoOptionsSnapshot.Value.IsExtendable && Model.PremiumEndDate!.Value.IsBetween(DateTime.Now, DateTime.Now.AddMonths(PremiumPlanInfoOptionsSnapshot.Value.OnePremiumPeriodAsMonth - PremiumPlanInfoOptionsSnapshot.Value.CanBeExtendedAfterHowManyMonths)))
{
<div class="d-grid gap-2">
<a href="@Url.Page("/Pricing", new { organizationName = Model.Name })" class="btn btn-info">
<i class="fas fa-crown me-2"></i> Extend Now
</a>
</div>
}
else
{
<div class="d-grid gap-2">
<button class="btn btn-info">
<span class="mt-2">Premium end date: @Model.PremiumEndDate!.Value.ToShortDateString()</span>
</button>
</div>
}
}
else
{
<div class="d-grid gap-2">
<a href="@Url.Page("/Pricing", new { organizationName = Model.Name })" class="btn btn-info">
<i class="fas fa-crown me-2"></i> Upgrade To @PremiumPlanInfoOptionsSnapshot.Value.PlanType
</a>
</div>
}
}
else
{
<abp-card class="text-center">
<abp-card-body>
<span>Premium end date: @Model.PremiumEndDate!.Value.ToShortDateString()</span>
</abp-card-body>
</abp-card>
}
</abp-column>
</abp-row>
</abp-container>

43
src/EventHub.Web/Pages/Organizations/Profile.cshtml

@ -8,6 +8,7 @@
@using EventHub.Web.PaymentRequests
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.SweetAlert2
@using Volo.Abp.Timing
@model EventHub.Web.Pages.Organizations.ProfilePageModel
@inject IClock Clock
@ -15,6 +16,7 @@
@inject IOptionsSnapshot<PremiumPlanInfoOptions> PremiumPlanInfoOptionsSnapshot
@section scripts {
<abp-script type="@typeof(Sweetalert2ScriptContributor)"/>
<abp-script src="/Pages/Organizations/Profile.js"/>
}
@ -66,44 +68,7 @@
@if (Model.IsOrganizationOwner)
{
<a href="/organization/edit/@Model.Organization.Name" class="btn btn-primary mt-4 text-white">
<i class="far fa-edit"></i> Edit
</a>
@if (PremiumPlanInfoOptionsSnapshot.Value.IsActive)
{
<abp-card class="detail-head mt-4 font-weight-bold text-center">
<abp-card-body>
@if (Model.Organization.IsPremium)
{
<span>Premium end date: @Model.Organization.PremiumEndDate!.Value.ToShortDateString()</span>
@if (PremiumPlanInfoOptionsSnapshot.Value.IsExtendable && Model.Organization.PremiumEndDate!.Value.IsBetween(DateTime.Now, DateTime.Now.AddMonths(PremiumPlanInfoOptionsSnapshot.Value.OnePremiumPeriodAsMonth - PremiumPlanInfoOptionsSnapshot.Value.CanBeExtendedAfterHowManyMonths)))
{
<div class="d-grid gap-2">
<a href="@Url.Page("/Pricing", new { organizationName = Model.Organization.Name })" class="btn btn-primary mt-3">
<i class="fas fa-handshake"></i> @L["ExtendNow"].Value
</a>
</div>
}
}
else
{
<div class="d-grid gap-2">
<a href="@Url.Page("/Pricing", new { organizationName = Model.Organization.Name })" class="btn btn-primary">
<i class="fas fa-handshake"></i> @L["UpgradeToPremium"]
</a>
</div>
}
</abp-card-body>
</abp-card>
}else if (Model.Organization.IsPremium)
{
<abp-card class="detail-head mt-4 font-weight-bold text-center">
<abp-card-body>
<span>Premium end date: @Model.Organization.PremiumEndDate!.Value.ToShortDateString()</span>
</abp-card-body>
</abp-card>
}
<partial name="Components/_upgradeOrExtendOrganizationSection.cshtml" model="@Model.Organization"/>
}
@await Component.InvokeAsync(typeof(JoinAreaViewComponent), new {organizationId = Model.Organization.Id})
@await Component.InvokeAsync(typeof(MembersAreaViewComponent),
@ -212,4 +177,4 @@
</div>
</div>
</div>
</div>
</div>

29
src/EventHub.Web/Pages/Organizations/Profile.js

@ -1,13 +1,36 @@
$(function () {
$('.events > .nav-item > a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var target = $(e.target).attr("href")
if (target === "#UpcomingEvent"){
if (target === "#UpcomingEvent") {
$("a[href='#PastEvent']").removeClass('selected');
$("a[href='#UpcomingEvent']").addClass('selected');
}else{
} else {
$("a[href='#UpcomingEvent']").removeClass('selected');
$("a[href='#PastEvent']").addClass('selected');
}
});
});
var searchParams = new URLSearchParams(window.location.search);
var paymentRequestId = searchParams.get('paymentRequestId');
if (paymentRequestId.length === 36) {
payment.paymentRequests.paymentRequest
.get(paymentRequestId)
.then(function (r) {
if (r.extraProperties.Status === "COMPLETED") {
Swal.fire({
title: 'Thank you for your purchase!',
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam utnulla consequat.',
imageUrl: '/assets/success.svg',
imageHeight: "70",
imageWidth: "70",
showCloseButton: true,
confirmButtonText: 'Close'
}).then(() => {
window.location.replace(window.location.pathname)
});
}
});
}
});

77
src/EventHub.Web/Pages/Payment/CustomPostCheckout.cshtml.cs

@ -0,0 +1,77 @@
using System;
using System.Threading.Tasks;
using EventHub.Organizations;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Payment.PaymentRequests;
using Payment.Web;
using Payment.Web.Pages.Payment;
using Payment.Web.PaymentRequest;
namespace EventHub.Web.Pages.Payment;
public class CustomPostCheckoutPageModel : PostCheckoutPageModel
{
public string OrganizationName { get; set; }
public CustomPostCheckoutPageModel(
IPaymentRequestAppService appService,
IOptions<PaymentWebOptions> paymentWebOptions,
IPaymentUrlBuilder paymentUrlBuilder)
: base(
appService,
paymentWebOptions,
paymentUrlBuilder)
{
}
public override async Task<IActionResult> OnGetAsync()
{
if (Token.IsNullOrWhiteSpace())
{
return BadRequest();
}
PaymentRequest = await PaymentRequestAppService.CompleteAsync(Token);
FillOrganizationName();
PaymentWebOptions.PaymentSuccessfulCallbackUrl = Url.Page("/Organizations/Profile", new { name = OrganizationName });
GoBackLink = PaymentUrlBuilder.BuildCheckoutUrl(PaymentRequest.Id).AbsoluteUri;
if (PaymentRequest.State == PaymentRequestState.Completed
&& !PaymentWebOptions.PaymentSuccessfulCallbackUrl.IsNullOrWhiteSpace())
{
var callbackUrl = PaymentWebOptions.PaymentSuccessfulCallbackUrl + "?paymentRequestId=" + PaymentRequest.Id;
Response.Redirect(callbackUrl);
}
if (PaymentRequest.State == PaymentRequestState.Failed
&& !PaymentWebOptions.PaymentFailureCallbackUrl.IsNullOrWhiteSpace())
{
var callbackUrl = PaymentWebOptions.PaymentFailureCallbackUrl + "?paymentRequestId=" + PaymentRequest.Id;
Response.Redirect(callbackUrl);
}
return Page();
}
private void FillOrganizationName()
{
var isExistExtraProperties = PaymentRequest.ExtraProperties.TryGetValue(nameof(OrganizationPaymentRequestExtraParameterConfiguration), out var ExtraProperties);
if (!isExistExtraProperties)
{
throw new BadHttpRequestException("");
}
var organizationPaymentExtraParameterConfiguration = JsonConvert.DeserializeObject<OrganizationPaymentRequestExtraParameterConfiguration>(ExtraProperties.ToString());
if (organizationPaymentExtraParameterConfiguration is null)
{
throw new BadHttpRequestException("");
}
OrganizationName = organizationPaymentExtraParameterConfiguration.OrganizationName;
}
}

23
src/EventHub.Web/Pages/Payment/PostCheckout.cshtml

@ -1,32 +1,15 @@
@page
@using EventHub.Organizations
@using EventHub.Web
@using Microsoft.AspNetCore.Http
@using Microsoft.Extensions.Options
@using Newtonsoft.Json
@using Payment.Web.Pages.Payment
@using Payment.PaymentRequests
@using Volo.Abp.Users
@inherits Payment.Web.Pages.PaymentPageBase
@model Payment.Web.Pages.Payment.PostCheckoutPageModel
@model EventHub.Web.Pages.Payment.CustomPostCheckoutPageModel
@inject IOptions<EventHubUrlOptions> UrlOptions
@inject ICurrentUser CurrentUser
@{
PageLayout.Content.Title = L["PaymentResult"] + L["Enum:PaymentRequestState:" + Model.PaymentRequest.State];
var isExistExtraProperties = Model.PaymentRequest.ExtraProperties.TryGetValue(nameof(OrganizationPaymentRequestExtraParameterConfiguration), out var ExtraProperties);
if (!isExistExtraProperties)
{
throw new BadHttpRequestException("");
}
var organizationPaymentExtraParameterConfiguration = JsonConvert.DeserializeObject<OrganizationPaymentRequestExtraParameterConfiguration>(ExtraProperties.ToString());
if (organizationPaymentExtraParameterConfiguration is null)
{
throw new BadHttpRequestException("");
}
var organizationName = organizationPaymentExtraParameterConfiguration.OrganizationName;
}
<main class="static-page container mt-5 text-center">
@ -69,8 +52,8 @@
<div class="col-md-8 mx-auto text-center">
<hr class="mt-4 mb-5" />
<a href="/" class="btn btn-sm btn-outline-primary">Home page</a>
<a href="@UrlOptions.Value.Www/organizations/@organizationName" class="btn btn-sm btn-primary">My Organization</a>
<a href="@UrlOptions.Value.Www/organizations/@Model.OrganizationName" class="btn btn-sm btn-primary">My Organization</a>
</div>
</div>
</div>
</main>
</main>

115
src/EventHub.Web/Pages/Payment/PreCheckout.cshtml

@ -31,79 +31,42 @@
<abp-script src="/client-proxies/Payment-proxy.js" />
</abp-script-bundle>
}
<div class="container px-3 my-5 clearfix">
<abp-card>
<abp-card-header><h5>Shopping Cart</h5></abp-card-header>
<abp-card-body>
<div class="table-responsive">
<table class="table table-bordered m-0">
<thead>
<tr>
<th class="text-center py-3 px-4" style="min-width: 400px;">Product Name &amp; Details</th>
<th class="text-center py-3 px-4" style="width: 100px;">Total</th>
</tr>
</thead>
<tbody>
<tr>
<td class="p-4">
<div class="media align-items-center">
<div class="media-body">
<p class="font-weight-bolder">@Model.PaymentRequest.ProductName</p>
<small>
@if (!organizationPaymentRequestExtraParameterConfiguration.IsExtend)
{
<span class="text-muted">Target Plan: @OrganizationPlanType.Premium</span>
<span class="text-muted ms-1">End date: @DateTime.Now.AddMonths(planInfo.OnePremiumPeriodAsMonth).ToShortDateString()</span>
}
else
{
<span class="text-muted">Plan: @OrganizationPlanType.Premium</span>
}
<span class="ui-product-color ui-product-color-sm align-text-bottom" style="background:#e81e2c;"></span> &nbsp;
</small>
</div>
</div>
</td>
<td class="text-center font-weight-semibold align-middle">@Model.PaymentRequest.Price @Model.PaymentRequest.Currency</td>
</tr>
</tbody>
</table>
</div>
<div class="d-flex flex-wrap justify-content-between align-items-center pb-4">
<abp-container>
<abp-row class="float-end">
<abp-column>
<div class="text-end mt-4">
<label class="text-muted font-weight-normal m-0">Total price</label>
<div class="text-large"><strong>@Model.PaymentRequest.Price @Model.PaymentRequest.Currency</strong></div>
</div>
</abp-column>
</abp-row>
</abp-container>
</div>
<abp-container class="float-end">
<abp-row>
<abp-column class="float-end">
<form method="post">
@if (Model.PaymentRequest.State != PaymentRequestState.Waiting)
{
<abp-alert alert-type="Info">Current State: @Model.PaymentRequest.State</abp-alert>
<abp-alert alert-type="Warning">@L["PaymentRequestIsNotWaiting"]</abp-alert>
}
else
{
<abp-button class="mt-2 float-end" offset="_10" size="Large" type="submit" button-type="Primary">@L["Checkout"]</abp-button>
<a href="@Url.Page("/Pricing", new { organizationName = organizationName })" class="btn btn-lg btn-default md-btn-flat mt-2 me-3 float-end">Back to pricing</a>
}
</form>
</abp-column>
</abp-row>
</abp-container>
</abp-card-body>
</abp-card>
</div>
<main class="static-page container mt-5">
<h1 class="text-center mb-3">Shopping Cart</h1>
<div class="row">
<div class="col-md-7">
<div class="card">
<div class="card-body px-5 py-4">
<h2 class="my-4">Product Detail</h2>
<h3 class="my-4">@OrganizationPlanType.Premium Account: <span class="text-primary">@organizationName.ToUpperInvariant()</span></h3>
@if (!organizationPaymentRequestExtraParameterConfiguration.IsExtend)
{
<p>Start Date: <span class="text-dark">@DateTime.Now.ToShortDateString()</span></p>
<p>End Date: <span class="text-dark">@DateTime.Now.AddMonths(planInfo.OnePremiumPeriodAsMonth).ToShortDateString()</span></p>
}
else
{
<p>Your license will be extended for <span class="text-dark">@planInfo.OnePremiumPeriodAsMonth</span> months.</p>
}
</div>
</div>
</div>
<div class="col-md-5">
<div class="card">
<div class="card-body px-5 py-4">
<h2 class="mt-4">Summary</h2>
<div class="cart-summary pt-3 pb-2">
<p class="my-4">Premium Licence <span class="text-dark float-end">@Model.PaymentRequest.Price @Model.PaymentRequest.Currency</span></p>
<hr>
<p class="my-4">TOTAL <span class="text-dark float-end">@Model.PaymentRequest.Price @Model.PaymentRequest.Currency</span></p>
</div>
<form method="post">
<div class="d-grid gap-2">
<button type="submit" class="btn btn-info my-4">@L["Checkout"]</button>
</div>
</form>
</div>
</div>
</div>
</div>
</main>

231
src/EventHub.Web/Pages/Pricing.cshtml

@ -8,129 +8,114 @@
<abp-style src="/Pages/Pricing.css" />
}
<div class="container-fluid flex-grow-1 container-p-y pricing-table">
<div class="container px-0">
<h1 class="text-center font-weight-bolder pt-5 mb-3">
Pricing plans
</h1>
<div class="text-center text-muted text-large font-weight-light">
Choose the plan best for your organization.
</div>
<div class="row no-gutters row-bordered ui-bordered text-center mt-3">
<div class="d-flex col-md flex-column py-4">
<div class="display-1 text-primary my-4"><i class="lnr lnr-briefcase text-big"></i></div>
<h5 class="m-0 ms-2">Free account</h5>
<div class="flex-grow-1">
<div class="py-4 my-2">
<span class="d-inline-block text-muted text-big align-middle me-2">$</span>
<span class="display-3 d-inline-block font-weight-bold align-middle">0</span>
</div>
<div class="pb-5">
<p class="ui-company-text mb-2">1 event per month</p>
<p class="ui-company-text mb-2">300 attendees per event</p>
</div>
<main class="static-page container mt-5">
<h1 class="text-center mb-3">Eventhub Pricing List</h1>
<p class="text-center mb-5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ut nulla consequat, tempus sapien in,
pellentesque nunc. Sed at nunc pellentesque, fermentum mi et, fermentum massa. </p>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-body px-4 py-4 text-center">
<h2 class="mt-4">Normal Account</h2>
<p class="my-4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam utnulla consequat, tempus sapien in.</p>
<div class="price mb-4">
<small>$</small>
<span>0</span>
</div>
<ul class="list-check-icon mb-4 text-start">
<li><i class="fa fa-check-circle"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </li>
<li><i class="fa fa-check-circle"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </li>
<li><i class="fa fa-check-circle"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </li>
</ul>
</div>
</div>
</div>
<div class="px-md-3 px-lg-5">
@if (Model.PremiumPlanInfo is not null)
{
<div class="col-md-6">
<div class="card">
<div class="card-body px-4 py-4 text-center">
<h2 class="mt-4">Premium Account</h2>
<p class="my-4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam utnulla consequat, tempus sapien in.</p>
<div class="price mb-4">
<small>$</small>
<span>@Model.PremiumPlanInfo.Price</span>
</div>
<ul class="list-check-icon mb-4 text-start">
<li><i class="fa fa-check-circle"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </li>
<li><i class="fa fa-check-circle"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </li>
<li><i class="fa fa-check-circle"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit adipiscing elit. </li>
<li><i class="fa fa-check-circle"></i> Lorem ipsum adipiscing elit dolor sit amet, consectetur adipiscing elit. </li>
<li><i class="fa fa-check-circle"></i> Lorem adipiscing elit adipiscing elitipsum dolor sit amet, consectetur adipiscing elit. </li>
<li><i class="fa fa-check-circle"></i> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </li>
</ul>
@if (Model.Organization.IsPremium)
{
<form id="Extend" method="post" asp-page-handler="Extend">
<abp-input asp-for="TargetPlanToUpgrade" value="@Model.PremiumPlanInfo.PlanType"></abp-input>
<abp-input asp-for="OrganizationName"></abp-input>
<a onclick="document.getElementById('Extend').submit()" class="btn btn-info my-4"><i class="fas fa-crown me-2"></i> Extend Now</a>
</form>
}
else
{
<form id="Upgrade" method="post" asp-page-handler="Upgrade">
<abp-input asp-for="TargetPlanToUpgrade" value="@Model.PremiumPlanInfo.PlanType"></abp-input>
<abp-input asp-for="OrganizationName"></abp-input>
<a onclick="document.getElementById('Upgrade').submit()" class="btn btn-info my-4"><i class="fas fa-crown me-2"></i> Upgrade to @Model.PremiumPlanInfo.PlanType</a>
</form>
}
</div>
</div>
</div>
}
<h2 class="text-center mb-3">Frequently Asked Questions</h2>
<div id="accordion" class="mb-5 pb-5 faq-container">
<div class="faq shown" data-anchor-id="accordion1">
<div class="faq-header">
<h5><button class="btn btn-faq" data-bs-toggle="collapse" data-bs-target="#accordion1" aria-expanded="false" aria-controls="accordion1">Lorem ipsum dolor sit amet, consectetur adipiscing elit?<i class="fas fa-chevron-up"></i> </button></h5>
</div>
<div id="accordion1" class="collapse show" data-bs-parent="#accordion" style="">
<div class="faq-body">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
</div>
</div>
</div>
<div class="faq" data-anchor-id="accordion12">
<div class="faq-header">
<h5><button class="btn btn-faq collapsed" data-bs-toggle="collapse" data-bs-target="#accordion12" aria-expanded="false" aria-controls="accordion12">What onsectetur adipiscinglor sit amet?<i class="fas fa-chevron-up"></i> </button></h5>
</div>
<div id="accordion12" class="collapse" data-bs-parent="#accordion" style="">
<div class="faq-body">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
</div>
</div>
</div>
<div class="faq" data-anchor-id="accordion123">
<div class="faq-header">
<h5><button class="btn btn-faq collapsed" data-bs-toggle="collapse" data-bs-target="#accordion123" aria-expanded="false" aria-controls="accordion123">What onsectetur adipiscing elit. Lorem ipsum dolor sit amet?<i class="fas fa-chevron-up"></i> </button></h5>
</div>
<div id="accordion123" class="collapse" data-bs-parent="#accordion" style="">
<div class="faq-body">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
</div>
</div>
</div>
<div class="faq" data-anchor-id="accordion124">
<div class="faq-header">
<h5><button class="btn btn-faq collapsed" data-bs-toggle="collapse" data-bs-target="#accordion124" aria-expanded="false" aria-controls="accordion124">Asectetur adipiscing elorem ipsum dolor sit amet?<i class="fas fa-chevron-up"></i> </button></h5>
</div>
<div id="accordion124" class="collapse" data-bs-parent="#accordion" style="">
<div class="faq-body">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
</div>
</div>
</div>
</div>
</div>
@if(Model.PremiumPlanInfo is not null)
{
<div class="d-flex col-md flex-column py-4">
<div class="display-1 text-primary my-4"><i class="lnr lnr-store text-big"></i></div>
<h5 class="m-0">
@Model.PremiumPlanInfo.PlanType account
@if (Model.Organization.IsPremium)
{
<span class="align-top text-dark font-weight-bold" style="font-size: x-small" abp-badge-pill="Info"> Current Plan </span>
}
</h5>
<div class="flex-grow-1">
<div class="py-4 my-2">
<span class="d-inline-block text-muted text-big align-middle me-2">$</span>
<span class="display-3 d-inline-block font-weight-bold align-middle">@Model.PremiumPlanInfo.Price</span>
</div>
<div class="pb-5">
<p class="ui-company-text mb-2">unlimited events</p>
<p class="ui-company-text mb-2">unlimited attendees</p>
</div>
</div>
<div class="px-md-3 px-lg-5">
@if (Model.Organization.IsPremium)
{
<form id="Extend" method="post" asp-page-handler="Extend">
<abp-input asp-for="TargetPlanToUpgrade" value="@Model.PremiumPlanInfo.PlanType"></abp-input>
<abp-input asp-for="OrganizationName"></abp-input>
<a onclick="document.getElementById('Extend').submit()" class="btn btn-primary btn-lg rounded-pill">Extend Now</a>
</form>
}
else
{
<form id="Upgrade" method="post" asp-page-handler="Upgrade">
<abp-input asp-for="TargetPlanToUpgrade" value="@Model.PremiumPlanInfo.PlanType"></abp-input>
<abp-input asp-for="OrganizationName"></abp-input>
<a onclick="document.getElementById('Upgrade').submit()" class="btn btn-primary btn-lg rounded-pill">Upgrade To @Model.PremiumPlanInfo.PlanType</a>
</form>
}
</div>
</div>
}
</div>
@*
<h3 class="text-center font-weight-light my-5">Frequently Asked Questions</h3>
<div class="row">
<div class="col-md-6">
<h5 class="mb-2">Dapibus ac facilisis in?</h5>
<p class="ui-company-text text-muted mb-4">
Lorem ipsum dolor sit amet, ius virtute suscipit te. Ius prima euismod consequat eu.
</p>
<h5 class="mb-2">Cras justo odio?</h5>
<p class="ui-company-text text-muted mb-4">
Etiam vivendo eu sea, purto ponderum mediocritatem at pro.
</p>
<h5 class="mb-2">Porta ac consectetur ac?</h5>
<p class="ui-company-text text-muted mb-4">
Iuvaret deleniti vulputate nec ne, id vix lucilius legendos deseruisse.
</p>
<h5 class="mb-2">Ne ornatus albucius ius?</h5>
<p class="ui-company-text text-muted mb-4">
Lorem ipsum dolor sit amet, mea in pertinax hendrerit gloriatur.
</p>
</div>
<div class="col-md-6">
<h5 class="mb-2">Ne ornatus albucius ius?</h5>
<p class="ui-company-text text-muted mb-4">
Lorem ipsum dolor sit amet, mea in pertinax hendrerit gloriatur.
</p>
<h5 class="mb-2">Quo insolens intellegam dissentiet at?</h5>
<p class="ui-company-text text-muted mb-4">
Ex fugit legimus fuisset per. Ex quidam option diceret ius.
</p>
<h5 class="mb-2">Ad his assum delenit blandit?</h5>
<p class="ui-company-text text-muted mb-4">
Ne ornatus albucius ius, nostrum dignissim repudiandae an usu.
</p>
<h5 class="mb-2">Dapibus ac facilisis in?</h5>
<p class="ui-company-text text-muted mb-4">
Lorem ipsum dolor sit amet, ius virtute suscipit te. Ius prima euismod consequat eu.
</p>
</div>
</div>
*@
</div>
</div>
</main>

1
src/EventHub.Web/wwwroot/assets/success.svg

@ -0,0 +1 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M24 0C10.7669 0 0 10.7669 0 24C0 37.2331 10.7669 48 24 48C37.2331 48 48 37.2331 48 24C48 10.7669 37.2331 0 24 0ZM37.4135 17.6842L22.0752 32.9023C21.1729 33.8045 19.7293 33.8647 18.7669 32.9624L10.6466 25.5639C9.68421 24.6617 9.62406 23.1579 10.4662 22.1955C11.3684 21.2331 12.8722 21.1729 13.8346 22.0752L20.2707 27.9699L33.985 14.2556C34.9474 13.2932 36.4511 13.2932 37.4135 14.2556C38.3759 15.218 38.3759 16.7218 37.4135 17.6842Z" fill="#6F32E2"/> </svg>

After

Width:  |  Height:  |  Size: 561 B

Loading…
Cancel
Save