Files
donations/views/settings/index.php

636 lines
37 KiB
PHP

<?php
use humhub\modules\donations\models\DonationGoal;
use humhub\modules\donations\models\DonationSubscription;
use humhub\modules\donations\models\DonationTransaction;
use humhub\modules\donations\models\DonationWebhookEvent;
use humhub\modules\donations\models\forms\DonationGoalForm;
use humhub\modules\donations\models\forms\ProviderSettingsForm;
use yii\bootstrap\ActiveForm;
use yii\helpers\Html;
use yii\helpers\Json;
/* @var string|null $subNav */
/* @var ProviderSettingsForm $providerForm */
/* @var DonationGoalForm $goalForm */
/* @var DonationGoal[] $goals */
/* @var DonationTransaction[] $transactions */
/* @var DonationSubscription[] $subscriptions */
/* @var DonationWebhookEvent[] $webhookEvents */
/* @var array $animalOptions */
/* @var array $animalGalleryImageMap */
/* @var string $activeTab */
/* @var bool $schemaReady */
$goalTypeOptions = DonationGoal::goalTypeOptions();
$isEditingGoal = !empty($goalForm->id);
$showAnimalTargetField = $goalForm->goal_type === DonationGoal::TYPE_ANIMAL;
$hostInfo = Yii::$app->request->hostInfo;
$stripeWebhookUrl = $hostInfo . $providerForm->contentContainer->createUrl('/donations/donations/stripe-webhook');
$paypalWebhookUrl = $hostInfo . $providerForm->contentContainer->createUrl('/donations/donations/paypal-webhook');
$tabs = [
'general' => Yii::t('DonationsModule.base', 'General'),
'goals' => Yii::t('DonationsModule.base', 'Goals'),
'payment-providers' => Yii::t('DonationsModule.base', 'Payment Providers'),
'donation-history' => Yii::t('DonationsModule.base', 'Donation History'),
'advanced' => Yii::t('DonationsModule.base', 'Advanced'),
];
if (!array_key_exists($activeTab, $tabs)) {
$activeTab = 'general';
}
$tabUrl = static function (string $tab) use ($providerForm): string {
return $providerForm->contentContainer->createUrl('/donations/settings', ['tab' => $tab]);
};
?>
<div class="panel panel-default">
<div class="panel-heading"><?= Yii::t('DonationsModule.base', '<strong>Donations</strong> Settings') ?></div>
<?php if (!empty($subNav)): ?>
<?= $subNav ?>
<?php endif; ?>
<div class="panel-body">
<?php if (!$schemaReady): ?>
<div class="alert alert-warning" style="margin-bottom:14px;">
<?= Yii::t('DonationsModule.base', 'Donations schema is not initialized for this environment yet. Use the Advanced tab to run setup before configuring providers, goals, or history.') ?>
</div>
<?php endif; ?>
<ul class="nav nav-tabs" style="margin-bottom:14px;">
<?php foreach ($tabs as $tabKey => $tabLabel): ?>
<li class="<?= $activeTab === $tabKey ? 'active' : '' ?>">
<?= Html::a(Html::encode($tabLabel), $tabUrl($tabKey)) ?>
</li>
<?php endforeach; ?>
</ul>
<?php if ($activeTab === 'general'): ?>
<div class="panel panel-default" style="margin-bottom:0;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Default Currency') ?></div>
<div class="panel-body">
<?php if (!$schemaReady): ?>
<div class="alert alert-info" style="margin-bottom:0;">
<?= Yii::t('DonationsModule.base', 'Run Donations setup from the Advanced tab to enable General settings.') ?>
</div>
<?php else: ?>
<?php $generalForm = ActiveForm::begin(); ?>
<?= Html::hiddenInput('active_tab', 'general') ?>
<?= $generalForm->errorSummary($providerForm, ['class' => 'alert alert-danger']) ?>
<div class="row">
<div class="col-md-4">
<?= $generalForm->field($providerForm, 'default_currency')->textInput(['maxlength' => 8]) ?>
</div>
<div class="col-md-4">
<?= $generalForm->field($providerForm, 'animal_tile_extra_height_px')->input('number', [
'min' => 0,
'max' => 600,
'step' => 1,
])->hint(Yii::t('DonationsModule.base', 'Adds extra height to animal cards in pixels to accommodate donation overlays.')) ?>
</div>
<div class="col-md-8">
<?= $generalForm->field($providerForm, 'animal_donation_form_header')->textInput(['maxlength' => 255])
->hint(Yii::t('DonationsModule.base', 'Use [animal-name] to insert the animal name, e.g. "Your Donation directly supports [animal-name]".')) ?>
</div>
</div>
<?= Html::submitButton(Yii::t('DonationsModule.base', 'Save General Settings'), ['class' => 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<?php if ($activeTab === 'goals'): ?>
<div class="panel panel-default" style="margin-bottom:14px;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Donation Goals') ?></div>
<div class="panel-body">
<?php if (!$schemaReady): ?>
<div class="alert alert-info" style="margin-bottom:0;">
<?= Yii::t('DonationsModule.base', 'Run Donations setup from the Advanced tab to manage goals.') ?>
</div>
<?php else: ?>
<?php if ($isEditingGoal): ?>
<div class="alert alert-info" style="margin-bottom:12px;">
<?= Yii::t('DonationsModule.base', 'You are editing an existing goal.') ?>
<?= Html::a(
Yii::t('DonationsModule.base', 'Cancel'),
$tabUrl('goals'),
['class' => 'btn btn-xs btn-default', 'style' => 'margin-left:8px;']
) ?>
</div>
<?php endif; ?>
<?php $goalActiveForm = ActiveForm::begin([
'options' => ['enctype' => 'multipart/form-data'],
]); ?>
<?= $goalActiveForm->errorSummary($goalForm, ['class' => 'alert alert-danger']) ?>
<?= $goalActiveForm->field($goalForm, 'id')->hiddenInput()->label(false) ?>
<div class="row">
<div class="col-md-3"><?= $goalActiveForm->field($goalForm, 'goal_type')->dropDownList($goalTypeOptions) ?></div>
<div class="col-md-3" id="donation-goal-animal-field" style="display:<?= $showAnimalTargetField ? 'block' : 'none' ?>;">
<?= $goalActiveForm->field($goalForm, 'target_animal_id')->dropDownList($animalOptions, ['prompt' => Yii::t('DonationsModule.base', 'Select animal')]) ?>
</div>
<div class="col-md-4"><?= $goalActiveForm->field($goalForm, 'title') ?></div>
<div class="col-md-2"><?= $goalActiveForm->field($goalForm, 'target_amount')->input('number', ['step' => '0.01', 'min' => '0']) ?></div>
</div>
<?= $goalActiveForm->field($goalForm, 'description')->textarea(['rows' => 3]) ?>
<div class="panel panel-default" style="margin-bottom:12px;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Goal Image') ?></div>
<div class="panel-body">
<?= $goalActiveForm->field($goalForm, 'imageGalleryPath')->hiddenInput()->label(false) ?>
<div id="donation-goal-current-preview" style="margin-bottom:10px;"></div>
<div id="donation-goal-gallery-wrapper" style="margin-bottom:12px;">
<div id="donation-goal-gallery-options" style="display:flex;flex-wrap:wrap;"></div>
<div id="donation-goal-gallery-empty" class="text-muted" style="display:none;">
<?= Yii::t('DonationsModule.base', 'No gallery images found for this animal. You can upload a new image below.') ?>
</div>
</div>
<?= $goalActiveForm->field($goalForm, 'imageFile')->fileInput(['accept' => 'image/*']) ?>
</div>
</div>
<?= $goalActiveForm->field($goalForm, 'is_active')->checkbox() ?>
<?= Html::submitButton(
$isEditingGoal ? Yii::t('DonationsModule.base', 'Update Goal') : Yii::t('DonationsModule.base', 'Create Goal'),
['class' => 'btn btn-primary']
) ?>
<?php ActiveForm::end(); ?>
<?php endif; ?>
</div>
</div>
<div class="panel panel-default" style="margin-bottom:0;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Existing Goals') ?></div>
<div class="panel-body">
<?php if (empty($goals)): ?>
<div class="alert alert-info" style="margin-bottom:0;"><?= Yii::t('DonationsModule.base', 'No donation goals configured yet.') ?></div>
<?php else: ?>
<div class="table-responsive" style="margin-bottom:0;">
<table class="table table-condensed table-hover">
<thead>
<tr>
<th><?= Yii::t('DonationsModule.base', 'Title') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Type') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Progress') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Status') ?></th>
<th style="width:180px;"><?= Yii::t('DonationsModule.base', 'Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($goals as $goal): ?>
<tr>
<td><?= Html::encode($goal->title) ?></td>
<td><?= Html::encode($goalTypeOptions[$goal->goal_type] ?? $goal->goal_type) ?></td>
<td><?= number_format((float)$goal->current_amount, 2) ?> / <?= number_format((float)$goal->target_amount, 2) ?> <?= Html::encode($goal->currency) ?></td>
<td>
<?php if ((int)$goal->is_active === 1): ?>
<span class="label label-success"><?= Yii::t('DonationsModule.base', 'Active') ?></span>
<?php else: ?>
<span class="label label-default"><?= Yii::t('DonationsModule.base', 'Inactive') ?></span>
<?php endif; ?>
</td>
<td>
<?= Html::a(
Yii::t('DonationsModule.base', 'Edit'),
$providerForm->contentContainer->createUrl('/donations/settings', [
'tab' => 'goals',
'goalId' => (int)$goal->id,
]),
['class' => 'btn btn-xs btn-primary']
) ?>
<?= Html::a(
Yii::t('DonationsModule.base', 'Delete'),
$providerForm->contentContainer->createUrl('/donations/settings/delete-goal', ['id' => (int)$goal->id]),
[
'class' => 'btn btn-xs btn-danger',
'data-method' => 'post',
'data-confirm' => Yii::t('DonationsModule.base', 'Delete this donation goal?'),
]
) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<?php if ($activeTab === 'payment-providers'): ?>
<div class="panel panel-default" style="margin-bottom:0;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Payment Providers') ?></div>
<div class="panel-body">
<?php if (!$schemaReady): ?>
<div class="alert alert-info" style="margin-bottom:0;">
<?= Yii::t('DonationsModule.base', 'Run Donations setup from the Advanced tab to manage payment providers.') ?>
</div>
<?php else: ?>
<?php $providerActiveForm = ActiveForm::begin(); ?>
<?= Html::hiddenInput('active_tab', 'payment-providers') ?>
<?= $providerActiveForm->errorSummary($providerForm, ['class' => 'alert alert-danger']) ?>
<div class="alert alert-info" style="margin-bottom:12px;">
<?= Yii::t('DonationsModule.base', 'Sandbox mode automatically uses sandbox credentials. Disable sandbox mode to use live credentials.') ?>
</div>
<div class="row" style="margin-bottom:8px;">
<div class="col-md-4" style="padding-top:6px;"><?= $providerActiveForm->field($providerForm, 'sandbox_mode')->checkbox() ?></div>
</div>
<div class="row">
<div class="col-md-6">
<div class="panel panel-default" style="margin-bottom:12px;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'PayPal') ?></div>
<div class="panel-body" style="padding-bottom:4px;">
<div class="row">
<div class="col-md-6"><?= $providerActiveForm->field($providerForm, 'paypal_enabled')->checkbox() ?></div>
<div class="col-md-6"><?= $providerActiveForm->field($providerForm, 'paypal_recurring_enabled')->checkbox() ?></div>
</div>
<div class="panel panel-default" style="margin-bottom:8px;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Sandbox Credentials') ?></div>
<div class="panel-body" style="padding-bottom:4px;">
<?= $providerActiveForm->field($providerForm, 'paypal_sandbox_client_id') ?>
<?= $providerActiveForm->field($providerForm, 'paypal_sandbox_client_secret') ?>
<?= $providerActiveForm->field($providerForm, 'paypal_sandbox_webhook_id') ?>
</div>
</div>
<div class="panel panel-default" style="margin-bottom:0;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Live Credentials') ?></div>
<div class="panel-body" style="padding-bottom:4px;">
<?= $providerActiveForm->field($providerForm, 'paypal_live_client_id') ?>
<?= $providerActiveForm->field($providerForm, 'paypal_live_client_secret') ?>
<?= $providerActiveForm->field($providerForm, 'paypal_live_webhook_id') ?>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel panel-default" style="margin-bottom:12px;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Stripe') ?></div>
<div class="panel-body" style="padding-bottom:4px;">
<div class="row">
<div class="col-md-6"><?= $providerActiveForm->field($providerForm, 'stripe_enabled')->checkbox() ?></div>
<div class="col-md-6"><?= $providerActiveForm->field($providerForm, 'stripe_recurring_enabled')->checkbox() ?></div>
</div>
<div class="panel panel-default" style="margin-bottom:8px;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Sandbox Credentials') ?></div>
<div class="panel-body" style="padding-bottom:4px;">
<?= $providerActiveForm->field($providerForm, 'stripe_sandbox_publishable_key') ?>
<?= $providerActiveForm->field($providerForm, 'stripe_sandbox_secret_key') ?>
<?= $providerActiveForm->field($providerForm, 'stripe_sandbox_webhook_secret') ?>
</div>
</div>
<div class="panel panel-default" style="margin-bottom:0;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Live Credentials') ?></div>
<div class="panel-body" style="padding-bottom:4px;">
<?= $providerActiveForm->field($providerForm, 'stripe_live_publishable_key') ?>
<?= $providerActiveForm->field($providerForm, 'stripe_live_secret_key') ?>
<?= $providerActiveForm->field($providerForm, 'stripe_live_webhook_secret') ?>
</div>
</div>
</div>
</div>
</div>
</div>
<?= Html::submitButton(Yii::t('DonationsModule.base', 'Save Provider Settings'), ['class' => 'btn btn-primary']) ?>
<?php ActiveForm::end(); ?>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<?php if ($activeTab === 'donation-history'): ?>
<div class="panel panel-default" style="margin-bottom:14px;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Transactions') ?></div>
<div class="panel-body">
<?php if (!$schemaReady): ?>
<div class="alert alert-info" style="margin-bottom:0;">
<?= Yii::t('DonationsModule.base', 'Run Donations setup from the Advanced tab to view transaction history.') ?>
</div>
<?php elseif (empty($transactions)): ?>
<div class="alert alert-info" style="margin-bottom:0;"><?= Yii::t('DonationsModule.base', 'No transactions found.') ?></div>
<?php else: ?>
<div class="table-responsive" style="margin-bottom:0;">
<table class="table table-condensed table-hover">
<thead>
<tr>
<th>ID</th>
<th><?= Yii::t('DonationsModule.base', 'Provider') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Mode') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Status') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Amount') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Goal') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Checkout ID') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Payment ID') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Created') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($transactions as $transaction): ?>
<tr>
<td><?= (int)$transaction->id ?></td>
<td><?= Html::encode($transaction->provider) ?></td>
<td><?= Html::encode($transaction->mode) ?></td>
<td><?= Html::encode($transaction->status) ?></td>
<td><?= number_format((float)$transaction->amount, 2) ?> <?= Html::encode($transaction->currency) ?></td>
<td>#<?= (int)$transaction->goal_id ?></td>
<td style="max-width:180px;word-break:break-all;"><?= Html::encode((string)$transaction->provider_checkout_id) ?></td>
<td style="max-width:180px;word-break:break-all;"><?= Html::encode((string)$transaction->provider_payment_id) ?></td>
<td><?= Html::encode((string)$transaction->created_at) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
<div class="panel panel-default" style="margin-bottom:14px;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Subscriptions') ?></div>
<div class="panel-body">
<?php if (!$schemaReady): ?>
<div class="alert alert-info" style="margin-bottom:0;">
<?= Yii::t('DonationsModule.base', 'Run Donations setup from the Advanced tab to view subscription history.') ?>
</div>
<?php elseif (empty($subscriptions)): ?>
<div class="alert alert-info" style="margin-bottom:0;"><?= Yii::t('DonationsModule.base', 'No subscriptions found.') ?></div>
<?php else: ?>
<div class="table-responsive" style="margin-bottom:0;">
<table class="table table-condensed table-hover">
<thead>
<tr>
<th>ID</th>
<th><?= Yii::t('DonationsModule.base', 'Provider') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Status') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Amount') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Interval') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Subscription ID') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Created') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($subscriptions as $subscription): ?>
<tr>
<td><?= (int)$subscription->id ?></td>
<td><?= Html::encode($subscription->provider) ?></td>
<td><?= Html::encode($subscription->status) ?></td>
<td><?= number_format((float)$subscription->amount, 2) ?> <?= Html::encode($subscription->currency) ?></td>
<td><?= Html::encode((string)$subscription->interval_count) ?> <?= Html::encode((string)$subscription->interval_unit) ?></td>
<td style="max-width:220px;word-break:break-all;"><?= Html::encode((string)$subscription->provider_subscription_id) ?></td>
<td><?= Html::encode((string)$subscription->created_at) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
<div class="panel panel-default" style="margin-bottom:0;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Recent Webhook Events (Global)') ?></div>
<div class="panel-body">
<?php if (!$schemaReady): ?>
<div class="alert alert-info" style="margin-bottom:0;">
<?= Yii::t('DonationsModule.base', 'Run Donations setup from the Advanced tab to view webhook event history.') ?>
</div>
<?php elseif (empty($webhookEvents)): ?>
<div class="alert alert-info" style="margin-bottom:0;"><?= Yii::t('DonationsModule.base', 'No webhook events found.') ?></div>
<?php else: ?>
<div class="table-responsive" style="margin-bottom:0;">
<table class="table table-condensed table-hover">
<thead>
<tr>
<th>ID</th>
<th><?= Yii::t('DonationsModule.base', 'Provider') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Event Type') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Event ID') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Processed') ?></th>
<th><?= Yii::t('DonationsModule.base', 'Created') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($webhookEvents as $event): ?>
<tr>
<td><?= (int)$event->id ?></td>
<td><?= Html::encode($event->provider) ?></td>
<td><?= Html::encode((string)$event->event_type) ?></td>
<td style="max-width:220px;word-break:break-all;"><?= Html::encode((string)$event->provider_event_id) ?></td>
<td><?= (int)$event->is_processed === 1 ? Yii::t('DonationsModule.base', 'Yes') : Yii::t('DonationsModule.base', 'No') ?></td>
<td><?= Html::encode((string)$event->created_at) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<?php if ($activeTab === 'advanced'): ?>
<div class="well well-sm" style="margin-bottom:14px;">
<div style="font-weight:700;margin-bottom:6px;"><?= Yii::t('DonationsModule.base', 'Module Setup') ?></div>
<div style="margin-bottom:8px;">
<?= Yii::t('DonationsModule.base', 'Donations supports one-time and recurring contributions using PayPal and Stripe.') ?>
</div>
<div style="margin-bottom:10px;">
<?= Yii::t('DonationsModule.base', 'Run setup to apply pending Donations migrations and initialize defaults for this space.') ?>
</div>
<?= Html::a(
Yii::t('DonationsModule.base', 'Run Donations Setup'),
$providerForm->contentContainer->createUrl('/donations/settings/setup'),
[
'class' => 'btn btn-primary btn-sm',
'data-method' => 'post',
'data-confirm' => Yii::t('DonationsModule.base', 'Run Donations setup now for this space?'),
]
) ?>
</div>
<?php if (!$schemaReady): ?>
<div class="alert alert-warning" style="margin-bottom:0;">
<?= Yii::t('DonationsModule.base', 'Donations schema is not initialized for this environment yet. Run setup above to continue.') ?>
</div>
<?php else: ?>
<div class="alert alert-info" style="margin-bottom:12px;">
<div><strong><?= Yii::t('DonationsModule.base', 'Stripe Webhook URL') ?>:</strong> <?= Html::encode($stripeWebhookUrl) ?></div>
<div><strong><?= Yii::t('DonationsModule.base', 'PayPal Webhook URL') ?>:</strong> <?= Html::encode($paypalWebhookUrl) ?></div>
</div>
<div class="panel panel-default" style="margin-bottom:12px;">
<div class="panel-heading" style="font-weight:600;"><?= Yii::t('DonationsModule.base', 'Webhook Simulation Tools') ?></div>
<div class="panel-body" style="padding-bottom:8px;">
<p style="margin-bottom:10px;">
<?= Yii::t('DonationsModule.base', 'Use these tools to test webhook processing locally after creating donation intents. Latest matching transaction in this space is used automatically.') ?>
</p>
<div style="display:flex;gap:8px;flex-wrap:wrap;">
<?= Html::beginForm($providerForm->contentContainer->createUrl('/donations/settings/simulate-stripe-webhook'), 'post', ['style' => 'display:inline-block;']) ?>
<?= Html::submitButton(Yii::t('DonationsModule.base', 'Simulate Stripe Checkout Completed'), ['class' => 'btn btn-default btn-sm']) ?>
<?= Html::endForm() ?>
<?= Html::beginForm($providerForm->contentContainer->createUrl('/donations/settings/simulate-paypal-webhook'), 'post', ['style' => 'display:inline-block;']) ?>
<?= Html::submitButton(Yii::t('DonationsModule.base', 'Simulate PayPal Capture Completed'), ['class' => 'btn btn-default btn-sm']) ?>
<?= Html::endForm() ?>
</div>
</div>
</div>
<div>
<?= Html::beginForm($providerForm->contentContainer->createUrl('/donations/settings/reconcile-pending'), 'post', ['style' => 'display:inline-block;margin-bottom:0;']) ?>
<?= Html::submitButton(
Yii::t('DonationsModule.base', 'Reconcile Pending Transactions'),
[
'class' => 'btn btn-primary btn-sm',
'data-confirm' => Yii::t('DonationsModule.base', 'Attempt reconciliation for pending transactions in this space now?'),
]
) ?>
<?= Html::endForm() ?>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
<?php
$animalGalleryMapJson = Json::htmlEncode($animalGalleryImageMap);
$selectedImageUrl = trim((string)$goalForm->imageGalleryPath) !== ''
? trim((string)$goalForm->imageGalleryPath)
: trim((string)$goalForm->image_path);
$selectedImageUrlJson = Json::htmlEncode($selectedImageUrl);
$this->registerCss(<<<CSS
.donation-gallery-item {
border: 1px solid #ddd;
border-radius: 4px;
background: #fff;
}
.donation-gallery-item.is-active {
border-color: #337ab7;
box-shadow: 0 0 0 1px rgba(51, 122, 183, 0.25);
}
#donation-goal-current-preview img {
width: 120px;
height: 120px;
object-fit: cover;
border: 1px solid #ddd;
border-radius: 4px;
}
CSS
);
$this->registerJs(<<<JS
(function() {
var galleryMap = $animalGalleryMapJson;
var selectedImageUrl = $selectedImageUrlJson;
function setSelectedImage(url) {
$('#donationgoalform-imagegallerypath').val(url || '');
selectedImageUrl = url || '';
renderCurrentPreview();
renderGalleryOptions();
}
function renderCurrentPreview() {
var wrapper = $('#donation-goal-current-preview');
wrapper.empty();
if (!selectedImageUrl) {
wrapper.append('<span class="text-muted">No image selected.</span>');
return;
}
var image = $('<img>').attr('src', selectedImageUrl);
wrapper.append(image);
}
function renderGalleryOptions() {
var goalType = $('#donationgoalform-goal_type').val();
var animalId = $('#donationgoalform-target_animal_id').val();
var wrapper = $('#donation-goal-gallery-options');
var emptyState = $('#donation-goal-gallery-empty');
wrapper.empty();
if (goalType !== 'animal' || !animalId || !galleryMap[animalId] || !galleryMap[animalId].length) {
emptyState.show();
return;
}
emptyState.hide();
galleryMap[animalId].forEach(function(url) {
var button = $('<button type="button" class="donation-gallery-item" style="margin:0 8px 8px 0;padding:4px;"></button>');
button.attr('data-url', url);
if (selectedImageUrl === url) {
button.addClass('is-active');
}
button.append($('<img>').attr('src', url).css({
width: '72px',
height: '72px',
objectFit: 'cover'
}));
wrapper.append(button);
});
}
function toggleAnimalField() {
var goalType = $('#donationgoalform-goal_type').val();
var wrapper = $('#donation-goal-animal-field');
if (goalType === 'animal') {
wrapper.show();
} else {
wrapper.hide();
$('#donationgoalform-target_animal_id').val('');
}
renderGalleryOptions();
}
$(document).on('change', '#donationgoalform-goal_type', toggleAnimalField);
$(document).on('change', '#donationgoalform-target_animal_id', renderGalleryOptions);
$(document).on('click', '.donation-gallery-item', function() {
var url = $(this).data('url') || '';
setSelectedImage(url);
});
$(document).on('change', '#donationgoalform-imagefile', function() {
if (this.files && this.files.length > 0) {
setSelectedImage('');
}
});
toggleAnimalField();
renderCurrentPreview();
})();
JS
);