Skip to content

Commit

Permalink
Stripe portal link (#821)
Browse files Browse the repository at this point in the history
* create better named queries for ProductQuery frontend and hook them up where needed
* update the layout of subscription to include each active price
* introduce link as well as button for customer portal redirect
* add stripe and discord css color codes
* improve the color of subscription css
  • Loading branch information
proditis authored Jan 17, 2023
1 parent 4644d89 commit b2cc14e
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 65 deletions.
19 changes: 4 additions & 15 deletions frontend/assets/MaterialAsset.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class MaterialAsset extends AssetBundle
['//fonts.googleapis.com/css?family=Roboto:300,400,500,700|Roboto+Slab:400,700|Material+Icons|Roboto+Mono|Orbitron&display=swap', 'async'=>'async', 'crossorigin'=>"anonymous"],
['css/all.min.css?v=0.20.3', 'defer'=>'defer'],
'css/material-dashboard.css?v=0.20.0',
'css/material.css?v=0.20.3',
'css/material.css?v=0.21.0',
];

public $js=[
Expand All @@ -48,26 +48,16 @@ class MaterialAsset extends AssetBundle
['/js/plugins/sweetalert2.js','defer'=>'defer'],
/* Plugin for the Wizard, full documentation here: https://github.com/VinceG/twitter-bootstrap-wizard */
//'js/plugins/jquery.bootstrap-wizard.js',
/* Plugin for Select, full documentation here: http://silviomoreto.github.io/bootstrap-select */
// 'js/plugins/bootstrap-selectpicker.min.js', // XXX FIXME MOVE REGISTER TO profile/settings
/* Plugin for the DateTimePicker, full documentation here: https://eonasdan.github.io/bootstrap-datetimepicker/ */
//'js/plugins/bootstrap-datetimepicker.min.js',
/* DataTables.net Plugin, full documentation here: https://datatables.net/ */
//'js/plugins/jquery.dataTables.min.js',
/* Plugin for Tags, full documentation here: https://github.com/bootstrap-tagsinput/bootstrap-tagsinputs */
//'js/plugins/bootstrap-tagsinput.js',
/* Plugin for Fileupload, full documentation here: http://www.jasny.net/bootstrap/javascript/#fileinput */
//'js/plugins/jasny-bootstrap.min.js',
/* Full Calendar Plugin, full documentation here: https://github.com/fullcalendar/fullcalendar */
//'js/plugins/fullcalendar.min.js',
/* Vector Map plugin, full documentation here: http://jvectormap.com/documentation/ */
//'js/plugins/jquery-jvectormap.js',
/* Plugin for the Sliders, full documentation here: http://refreshless.com/nouislider/ */
//'js/plugins/nouislider.min.js',
/* Library for adding dinamically elements */
/* Library for adding dynamically elements */
'/js/plugins/arrive.min.js',
/* Chartist JS */
//'js/plugins/chartist.min.js',
/* Notifications Plugin */
['js/plugins/bootstrap-notify.min.js','defer'=>'defer'],
/* Control Center for Material Dashboard: parallax effects, scripts for the example pages etc */
Expand All @@ -77,9 +67,8 @@ class MaterialAsset extends AssetBundle
// 'https://maps.googleapis.com/maps/api/js?key=YOUR_KEY_HERE',
/******/
//'/js/cookieconsent.min.js', // Move this to only the pages needing it.
'/js/material-dashboard.js?v=0.20.3',
['/js/libechoctf.js?v=0.20.3','defer'=>'defer'],
// 'js/superfish.js'
'/js/material-dashboard.js?v=0.21.0',
['/js/libechoctf.js?v=0.21.0','defer'=>'defer'],
];

public $depends=[
Expand Down
31 changes: 27 additions & 4 deletions frontend/modules/subscription/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,9 @@ public function getProduct()
return $model->product;
}

public function getPortalButton($view)
public function getPortalButton($view,$button='<button class="btn btn-block btn-info font-weight-bold">Manage Billing</button>')
{
$form='<form id="manage-billing-form">
<button class="btn btn-block btn-info font-weight-bold">Manage Billing</button>
</form>';
$form='<form id="manage-billing-form">'.$button.'</form>';
$view->registerJs('const manageBillingForm = document.querySelector("#manage-billing-form");
manageBillingForm.addEventListener("submit", function(e) {
e.preventDefault();
Expand All @@ -112,4 +110,29 @@ public function getPortalButton($view)
');
return $form;
}
public static function getPortalLink($view,$link)
{
$view->registerJs('$("#stripePortal").on("click", function(e) {
e.preventDefault();
fetch("'.\yii\helpers\Url::to(['/subscription/default/redirect-customer-portal']).'", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"'.\Yii::$app->request->csrfParam.'": "'.\Yii::$app->request->csrfToken.'"
}),
})
.then((response) => response.json())
.then((data) => {
window.location.href = data.url;
})
.catch((error) => {
console.error("Error:", error);
});
});
');
return $link;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public function beforeAction($action) {
public function actionIndex()
{
$mine=PlayerSubscription::findOne(\Yii::$app->user->id);
$products=Product::find()->active()->orderBy(['weight'=>SORT_ASC,'name'=>SORT_ASC]);
$products=Product::find()->purchasable()->ordered();

$dataProvider=new ActiveDataProvider([
'query' => $products,
Expand Down
14 changes: 14 additions & 0 deletions frontend/modules/subscription/models/ProductQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ public function active()
return $this->andWhere('[[active]]=1');
}

public function hasPrice()
{
return $this->andWhere('id in (SELECT DISTINCT product_id FROM price)');
}

public function purchasable()
{
return $this->active()->hasPrice();
}

public function ordered()
{
return $this->orderBy(['weight'=>SORT_ASC,'name'=>SORT_ASC]);
}
/**
* {@inheritdoc}
* @return Product[]|array
Expand Down
81 changes: 53 additions & 28 deletions frontend/modules/subscription/views/default/_create.php
Original file line number Diff line number Diff line change
@@ -1,53 +1,78 @@
<?php
/* @var $this yii\web\View */

use \yii\helpers\Html;
use yii\widgets\ListView;

$subscription = Yii::$app->getModule('subscription');

?>
<div class="container">
<?php
echo ListView::widget([
'dataProvider' => $dataProvider,
'emptyText'=>'<p class="text-info"><b>'.\Yii::t('app','There are no subscriptions available at the moment...').'</b></p>',
'options'=>['class'=>'list-view row d-flex justify-content-center'],
'summary'=>false,
'itemOptions' => [
'tag' => false,
],
'itemView' => '_product',
'viewParams' => ['mine' => $mine],
]);?>
<?php
echo ListView::widget([
'dataProvider' => $dataProvider,
'emptyText' => '<p class="text-info"><b>' . \Yii::t('app', 'There are no subscriptions available at the moment...') . '</b></p>',
'options' => ['class' => 'list-view row d-flex justify-content-center'],
'summary' => false,
'itemOptions' => [
'tag' => false,
],
'itemView' => '_product',
'viewParams' => ['mine' => $mine],
]); ?>

<div class="row d-flex justify-content-center">
<?php if ($mine && $mine->subscription_id !== 'sub_vip') : ?>
<div class="col-md-5 col-sm-6">
<?php \app\widgets\Card::begin([
'header' => 'header-icon',
'type' => 'card-stats',
'icon' => '<i class="fa-brands fa-stripe"></i>',
'encode'=>false,
'color' => 'stripe',
'title' => '<b>'.\Yii::t('app', 'Stripe Customer Portal!').'</b>',
'footer' =>$subscription->getPortalLink($this,Html::a('Stripe Portal', ['/subscription/default/redirect-customer-portal'], [
'class' => 'h4 font-weight-bold btn btn-outline-stripe btn-block',
'id'=>'stripePortal',
])),
]); ?>
Go to your Stripe Portal to manage your payment details or subscription package.
<?php \app\widgets\Card::end(); ?>

</div>
<?php endif; ?>

<div class="col-md-5 col-sm-6">
<?php \app\widgets\Card::begin([
'header'=>'header-icon',
'type'=>'card-stats',
'icon'=>'<i class="fas fa-flag"></i>',
'color'=>'rose',
'title'=>\Yii::t('app','On premises CTF or Hackathon?'),
'footer'=>Html::mailto(\Yii::t('app','Contact us'),'info@echothrust.com',[
'class'=>'h4 font-weight-bold btn btn-outline-danger btn-block'
]),
]);?>
<?=\Yii::t('app','Want to run or host your own CTF, Hackathon or Cybersecurity exercises?')?>
<?php \app\widgets\Card::end();?>
'header' => 'header-icon',
'type' => 'card-stats',
'icon' => '<i class="fas fa-flag"></i>',
'color' => 'rose',
'encode'=>false,
'title' => '<b>'.\Yii::t('app', 'On premises CTF or Hackathon?').'</b>',
'footer' => Html::mailto(\Yii::t('app', 'Contact us'), 'info@echothrust.com', [
'class' => 'h4 font-weight-bold btn btn-outline-danger btn-block'
]),
]); ?>
<?= \Yii::t('app', 'Want to run or host your own CTF, Hackathon or Cybersecurity exercises?') ?>
<?php \app\widgets\Card::end(); ?>

</div>
</div>
</div>
<?php
$this->registerJs('
var stripe = Stripe("'.\Yii::$app->sys->stripe_publicApiKey.'");
var stripe = Stripe("' . \Yii::$app->sys->stripe_publicApiKey . '");
var createCheckoutSession = function(priceId) {
return fetch("'.\yii\helpers\Url::to(['/subscription/default/create-checkout-session']).'", {
return fetch("' . \yii\helpers\Url::to(['/subscription/default/create-checkout-session']) . '", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
priceId: priceId,
"'.Yii::$app->request->csrfParam.'": "'.Yii::$app->request->csrfToken.'"
"' . Yii::$app->request->csrfParam . '": "' . Yii::$app->request->csrfToken . '"
})
}).then(function(result) {
if (!result.ok) {
Expand All @@ -56,8 +81,8 @@
return result.json();
}).catch(function(error) {
Swal.fire(
"'.\Yii::t('app','Oooops!').'",
"'.\Yii::t('app','We cannot process your request at this time. <br/>Try again later or contact the support!').'<br/><small>[ "+error+" ]</small>",
"' . \Yii::t('app', 'Oooops!') . '",
"' . \Yii::t('app', 'We cannot process your request at this time. <br/>Try again later or contact the support!') . '<br/><small>[ "+error+" ]</small>",
"warning"
);
return false;
Expand Down
9 changes: 1 addition & 8 deletions frontend/modules/subscription/views/default/_product.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,17 @@
<div class="row">
<?php foreach ($model->prices as $price) : ?>
<?php if ($price->active) : ?>
<?php if ($mine && $model->inPrice($mine->price_id) !== null && $mine->active) : ?>
<div class="col"><?= yii\bootstrap\Button::widget([
'label' => intval($price->unit_amount / 100) . ' ' . $price->recurring_interval,
'options' => ['class' => 'btn-lg btn-danger', 'id' => 'mySub'],
]); ?></div>
<?php else : ?>
<div class="col"><?= yii\bootstrap\Button::widget([
'label' => "" . intval($price->unit_amount / 100) . '/' . $price->recurring_interval,
'options' => ['class' => 'btn '.$model->htmlOptions('class').' text-dark text-bold', 'id' => $model->shortcode . '_' . $price->recurring_interval],
]); ?></div>
<?php endif; ?>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
</div>
<?php
if ($mine && $model->inPrice($mine->price_id) !== null && $mine->active)
if ($mine && $model->inPrices($mine->price_id) !== null && $mine->active)
$this->registerJs('document
.getElementById("mySub")
.addEventListener("click", function(evt) {
Expand Down
15 changes: 6 additions & 9 deletions frontend/modules/subscription/views/default/pricing.css
Original file line number Diff line number Diff line change
Expand Up @@ -93,27 +93,24 @@
text-shadow: 4px 4px 1px rgba(0, 0, 0, 0.2);
box-shadow: 0 4px 0 rgba(0, 0, 0, 0.15);
}
.pricingTable.green .pricingTable-header{
background: #54A445;
}

.pricingTable.green .pricingTable-signup a{ background: linear-gradient(#54A445, #54A445); }
.pricingTable.green .pricingTable-header{ background: linear-gradient(#54A445, #61B136); }
.pricingTable.green .pricingTable-signup a{ background: linear-gradient(#54A445, #61B136); }
.pricingTable.green .pricing-content li:before{ background: #54A445; }

.pricingTable.blue .pricingTable-header{ background: #00bcd4; }
.pricingTable.blue .pricingTable-header{ background: linear-gradient(#0d98ba, #00bcd4); }
.pricingTable.blue .pricingTable-signup a{ background: linear-gradient(#00bcd4, #00bcd4); }

.pricingTable.blue .pricing-content li:before{ background: #00bcd4; }



.pricingTable .pricing-content li.disable:before{ background: #ED1925; }
@media only screen and (max-width: 990px){
.pricingTable{ margin-bottom: 40px; }
}

.btn.green {
background: #54A445;
background: linear-gradient(#54A445, #61B136);;
}
.btn.blue {
background: #00bcd4;
background: linear-gradient(#00bcd4, #00bcd4);
}
36 changes: 36 additions & 0 deletions frontend/web/css/material.css
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,42 @@ details.headshotters:not([open]) summary::after {
.text-discord {
color:#7289DA!important;
}
.bg-discord {
background:#7289DA!important;
}

.card .card-header-discord .card-icon {
background: linear-gradient(60deg,#8494ce,#7289DA);
}

.btn.btn-outline-discord {
color: #7289DA;
background-color: transparent;
border-color: #7289DA;
border-style: solid;
border-width: 1px;
}

.text-stripe {
color:#5433FF!important;
}

.bg-stripe {
background:#5433FF!important;
}

.card .card-header-stripe .card-icon {
background: linear-gradient(60deg,#4379FF,#5433FF);
}

.btn.btn-outline-stripe {
color: #5433FF;
background-color: transparent;
border-color: #5433FF;
border-style: solid;
border-width: 1px;
}

.markdown h1 {
font-size: 1.65em;
}
Expand Down

0 comments on commit b2cc14e

Please sign in to comment.