Files
animal_management/views/animals/add-progress-update.php
2026-04-04 13:13:00 -04:00

445 lines
19 KiB
PHP

<?php
use humhub\modules\animal_management\models\Animal;
use humhub\modules\animal_management\models\AnimalGalleryItem;
use humhub\modules\animal_management\models\forms\AnimalProgressUpdateForm;
use humhub\modules\space\models\Space;
use humhub\widgets\Button;
use yii\bootstrap\ActiveForm;
use yii\helpers\Html;
use yii\helpers\Json;
/* @var Space $space */
/* @var Animal $animal */
/* @var AnimalProgressUpdateForm $model */
/* @var string $returnTo */
/* @var AnimalGalleryItem[] $galleryItems */
/* @var bool $isInline */
$isInline = isset($isInline) ? (bool)$isInline : false;
$renderCustomField = static function (string $fieldKey, AnimalProgressUpdateForm $formModel, array $definitions): string {
if (!isset($definitions[$fieldKey])) {
return '';
}
$definition = $definitions[$fieldKey];
$inputType = (string)$definition['input_type'];
$label = (string)$definition['label'];
if ((int)$definition['required'] === 1) {
$label .= ' *';
}
$fieldName = "AnimalProgressUpdateForm[customFields][$fieldKey]";
$fieldValue = $formModel->customFields[$fieldKey] ?? '';
ob_start();
?>
<?php if ($inputType === 'textarea'): ?>
<div class="form-group">
<label class="control-label" for="animalprogressupdateform-customfields-<?= Html::encode($fieldKey) ?>"><?= Html::encode($label) ?></label>
<?= Html::textarea($fieldName, (string)$fieldValue, ['class' => 'form-control', 'rows' => 3, 'id' => "animalprogressupdateform-customfields-$fieldKey"]) ?>
</div>
<?php elseif ($inputType === 'boolean'): ?>
<div class="checkbox" style="margin-bottom:10px;">
<label>
<?= Html::hiddenInput($fieldName, '0') ?>
<?= Html::checkbox($fieldName, !empty($fieldValue), ['value' => '1']) ?>
<?= Html::encode($label) ?>
</label>
</div>
<?php elseif ($inputType === 'select'): ?>
<div class="form-group">
<label class="control-label" for="animalprogressupdateform-customfields-<?= Html::encode($fieldKey) ?>"><?= Html::encode($label) ?></label>
<?= Html::dropDownList(
$fieldName,
(string)$fieldValue,
$formModel->getCustomFieldSelectOptions($fieldKey),
['class' => 'form-control', 'prompt' => Yii::t('AnimalManagementModule.base', 'Select...'), 'id' => "animalprogressupdateform-customfields-$fieldKey"]
) ?>
</div>
<?php elseif ($inputType === 'number'): ?>
<div class="form-group">
<label class="control-label" for="animalprogressupdateform-customfields-<?= Html::encode($fieldKey) ?>"><?= Html::encode($label) ?></label>
<?= Html::input('number', $fieldName, (string)$fieldValue, ['class' => 'form-control', 'step' => 'any', 'id' => "animalprogressupdateform-customfields-$fieldKey"]) ?>
</div>
<?php elseif ($inputType === 'date'): ?>
<div class="form-group">
<label class="control-label" for="animalprogressupdateform-customfields-<?= Html::encode($fieldKey) ?>"><?= Html::encode($label) ?></label>
<?= Html::input('date', $fieldName, (string)$fieldValue, ['class' => 'form-control', 'id' => "animalprogressupdateform-customfields-$fieldKey"]) ?>
</div>
<?php elseif ($inputType === 'datetime'): ?>
<div class="form-group">
<label class="control-label" for="animalprogressupdateform-customfields-<?= Html::encode($fieldKey) ?>"><?= Html::encode($label) ?></label>
<?= Html::input('datetime-local', $fieldName, (string)$fieldValue, ['class' => 'form-control', 'id' => "animalprogressupdateform-customfields-$fieldKey"]) ?>
</div>
<?php else: ?>
<div class="form-group">
<label class="control-label" for="animalprogressupdateform-customfields-<?= Html::encode($fieldKey) ?>"><?= Html::encode($label) ?></label>
<?= Html::textInput($fieldName, (string)$fieldValue, ['class' => 'form-control', 'id' => "animalprogressupdateform-customfields-$fieldKey"]) ?>
</div>
<?php endif; ?>
<?php
return (string)ob_get_clean();
};
$customDefinitions = $model->getCustomFieldDefinitions();
$knownProgressKeys = ['progress_notes', 'routine_updates', 'media_reference'];
$otherCustomDefinitions = [];
foreach ($customDefinitions as $fieldKey => $definition) {
if (in_array($fieldKey, $knownProgressKeys, true)) {
continue;
}
$otherCustomDefinitions[$fieldKey] = $definition;
}
$currentMediaReference = trim((string)($model->customFields['media_reference'] ?? ''));
$progressFormId = 'add-progress-update-inline-form';
$this->registerCss(<<<CSS
.inline-add-shell.panel {
position: relative;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.22);
border-radius: 12px;
background: rgba(10, 18, 28, 0.36);
background-size: cover;
background-position: center;
}
.inline-add-shell.panel.has-media::before {
content: '';
position: absolute;
inset: 0;
background: rgba(10, 18, 28, 0.22);
pointer-events: none;
}
.inline-add-shell > .panel-body {
position: relative;
z-index: 1;
background: rgba(10, 18, 28, 0.2);
}
.inline-add-shell .panel.panel-default {
border-color: rgba(255, 255, 255, 0.2);
background: rgba(10, 18, 28, 0.34);
}
.inline-add-shell .panel.panel-default > .panel-heading {
color: #eef5fb;
background: rgba(10, 18, 28, 0.42);
border-color: rgba(255, 255, 255, 0.2);
}
.inline-add-shell,
.inline-add-shell .panel-body,
.inline-add-shell .control-label,
.inline-add-shell .checkbox label,
.inline-add-shell .radio label,
.inline-add-shell .help-block {
color: #eef5fb;
}
.inline-add-shell .text-muted {
color: rgba(233, 242, 250, 0.78) !important;
}
.inline-add-shell .form-control {
background: rgba(10, 18, 28, 0.56);
border-color: rgba(255, 255, 255, 0.44);
color: #f3f8ff;
}
.inline-add-shell .form-control::placeholder {
color: rgba(243, 248, 255, 0.72);
}
.inline-add-shell .form-control[readonly],
.inline-add-shell .form-control[disabled] {
background: rgba(10, 18, 28, 0.42);
color: rgba(243, 248, 255, 0.72);
}
.inline-add-shell select.form-control option {
color: #0f1b2a;
}
CSS
);
if ($isInline) {
$this->registerCss(<<<CSS
html, body {
margin: 0 !important;
padding: 0 !important;
background: transparent !important;
}
body > .panel:first-child {
margin-top: 0 !important;
}
CSS
);
}
?>
<div class="panel panel-default inline-add-shell<?= $currentMediaReference !== '' ? ' has-media' : '' ?>" id="progress-inline-add-shell"<?= $currentMediaReference !== '' ? ' style="background-image:url(' . Html::encode($currentMediaReference) . ');"' : '' ?>>
<div class="panel-body">
<?php
$formOptions = ['id' => $progressFormId, 'enctype' => 'multipart/form-data'];
if (!$isInline) {
$formOptions['target'] = '_top';
}
$form = ActiveForm::begin(['options' => $formOptions]);
?>
<?= Html::hiddenInput('returnTo', (string)($returnTo ?? 'progress-updates')) ?>
<?php if ($isInline): ?>
<div style="display:flex;justify-content:flex-end;gap:8px;margin-bottom:10px;">
<?= Html::submitButton('<i class="fa fa-check"></i>', [
'class' => 'btn btn-default btn-sm',
'title' => Yii::t('AnimalManagementModule.base', 'Save Progress Update'),
'form' => $progressFormId,
]) ?>
<?= Html::button('<i class="fa fa-times"></i>', [
'type' => 'button',
'class' => 'btn btn-default btn-sm',
'id' => 'progress-inline-add-cancel-icon',
'title' => Yii::t('AnimalManagementModule.base', 'Cancel'),
]) ?>
</div>
<?php endif; ?>
<?= $form->errorSummary($model, ['showAllErrors' => true]) ?>
<div class="panel panel-default" style="margin-bottom:12px;">
<div class="panel-heading"><strong><?= Yii::t('AnimalManagementModule.base', 'Media') ?></strong></div>
<div class="panel-body" style="padding-bottom:8px;">
<input type="hidden" id="progress-media-gallery-path" name="progressMediaGalleryPath" value="<?= Html::encode($currentMediaReference) ?>">
<div class="row">
<div class="col-sm-4" style="margin-bottom:8px;">
<div id="progress-media-preview" style="border-radius:8px;overflow:hidden;background:#f2f4f6;height:150px;display:flex;align-items:center;justify-content:center;">
<?php if ($currentMediaReference !== '' && (preg_match('/^https?:\/\//i', $currentMediaReference) || substr($currentMediaReference, 0, 1) === '/')): ?>
<img src="<?= Html::encode($currentMediaReference) ?>" alt="<?= Yii::t('AnimalManagementModule.base', 'Selected media') ?>" style="width:100%;height:100%;object-fit:cover;">
<?php else: ?>
<i class="fa fa-image fa-2x" style="color:#a7b0b8;"></i>
<?php endif; ?>
</div>
</div>
<div class="col-sm-8">
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#progress-media-modal" style="margin-bottom:8px;">
<i class="fa fa-photo"></i> <?= Yii::t('AnimalManagementModule.base', 'Choose from Gallery or Upload') ?>
</button>
<div class="checkbox" style="margin-top:0;">
<label>
<input type="checkbox" name="removeProgressMedia" value="1">
<?= Yii::t('AnimalManagementModule.base', 'Remove selected media') ?>
</label>
</div>
</div>
</div>
</div>
</div>
<div class="panel panel-default" style="margin-bottom:12px;">
<div class="panel-heading"><strong><?= Yii::t('AnimalManagementModule.base', 'Progress Update') ?></strong></div>
<div class="panel-body" style="padding-bottom:8px;">
<div class="row">
<div class="col-sm-4"><?= $form->field($model, 'weight') ?></div>
<div class="col-sm-8"><?= $form->field($model, 'vitals')->textInput(['maxlength' => 255]) ?></div>
<div class="col-sm-6"><?= $form->field($model, 'behavior_notes')->textarea(['rows' => 2]) ?></div>
<div class="col-sm-6"><?= $form->field($model, 'medical_concerns')->textarea(['rows' => 2]) ?></div>
<div class="col-sm-6"><?= $form->field($model, 'meal_plan_changes')->textarea(['rows' => 2]) ?></div>
<div class="col-sm-6"><?= $form->field($model, 'housing_changes')->textarea(['rows' => 2]) ?></div>
</div>
</div>
</div>
<div class="panel panel-default" style="margin-bottom:12px;">
<div class="panel-heading"><strong><?= Yii::t('AnimalManagementModule.base', 'Notes') ?></strong></div>
<div class="panel-body" style="padding-bottom:8px;">
<?= $renderCustomField('progress_notes', $model, $customDefinitions) ?>
<?= $renderCustomField('routine_updates', $model, $customDefinitions) ?>
</div>
</div>
<?php if (!empty($otherCustomDefinitions)): ?>
<div class="panel panel-default" style="margin-bottom:12px;">
<div class="panel-heading"><strong><?= Yii::t('AnimalManagementModule.base', 'Additional Details') ?></strong></div>
<div class="panel-body" style="padding-bottom:8px;">
<?php foreach ($otherCustomDefinitions as $fieldKey => $definition): ?>
<?= $renderCustomField($fieldKey, $model, $otherCustomDefinitions) ?>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<div class="panel panel-default" style="margin-bottom:12px;">
<div class="panel-heading"><strong><?= Yii::t('AnimalManagementModule.base', 'Social Post') ?></strong></div>
<div class="panel-body" style="padding-bottom:8px;">
<?= $form->field($model, 'post_to_space_feed')->checkbox() ?>
<?= $form->field($model, 'post_to_animal_feed')->checkbox() ?>
</div>
</div>
<div class="modal fade" id="progress-media-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="<?= Yii::t('AnimalManagementModule.base', 'Close') ?>"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><?= Yii::t('AnimalManagementModule.base', 'Select Progress Media') ?></h4>
</div>
<div class="modal-body">
<?php if (empty($galleryItems)): ?>
<div class="text-muted" style="margin-bottom:10px;"><?= Yii::t('AnimalManagementModule.base', 'No gallery images available yet.') ?></div>
<?php else: ?>
<div class="row" style="max-height:280px;overflow:auto;margin-bottom:10px;">
<?php foreach ($galleryItems as $galleryItem): ?>
<?php $galleryUrl = trim((string)$galleryItem->getImageUrl()); ?>
<?php if ($galleryUrl === '') { continue; } ?>
<div class="col-xs-6 col-sm-4" style="margin-bottom:8px;">
<button type="button" class="btn btn-default progress-media-select-thumb<?= $currentMediaReference === $galleryUrl ? ' is-selected' : '' ?>" data-media-url="<?= Html::encode($galleryUrl) ?>" style="width:100%;padding:3px;">
<img src="<?= Html::encode($galleryUrl) ?>" alt="<?= Yii::t('AnimalManagementModule.base', 'Gallery image') ?>" style="width:100%;height:120px;object-fit:cover;border-radius:4px;">
</button>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<div class="form-group" style="margin-bottom:0;">
<label class="control-label" for="progressMediaUpload"><?= Yii::t('AnimalManagementModule.base', 'Upload New Image') ?></label>
<input type="file" class="form-control" id="progressMediaUpload" name="progressMediaUpload" accept="image/*">
</div>
</div>
</div>
</div>
</div>
<?= Button::save(Yii::t('AnimalManagementModule.base', 'Save Progress Update'))->submit() ?>
<?php if ($isInline): ?>
<?= Html::button(Yii::t('AnimalManagementModule.base', 'Cancel'), [
'type' => 'button',
'class' => 'btn btn-default',
'id' => 'progress-inline-add-cancel',
]) ?>
<?php else: ?>
<?= Button::asLink(Yii::t('AnimalManagementModule.base', 'Cancel'))
->link(($returnTo ?? 'progress-updates') === 'progress-updates'
? $space->createUrl('/animal_management/animals/progress-updates', ['id' => $animal->id])
: $space->createUrl('/animal_management/animals/view', ['id' => $animal->id])) ?>
<?php endif; ?>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php
$this->registerCss(<<<CSS
.progress-media-select-thumb.is-selected {
border-color: #2f7df4 !important;
box-shadow: 0 0 0 2px rgba(47, 125, 244, 0.22);
}
CSS
);
$this->registerJs(<<<JS
(function() {
function escapeCssUrl(source) {
return String(source || '').replace(/"/g, '\\"');
}
function setProgressShellBackground(source) {
var shell = $('#progress-inline-add-shell');
if (!shell.length) {
return;
}
if (source) {
shell.addClass('has-media').css('background-image', 'url("' + escapeCssUrl(source) + '")');
} else {
shell.removeClass('has-media').css('background-image', 'none');
}
}
function renderProgressPreview(source) {
var preview = $('#progress-media-preview');
if (!preview.length) {
return;
}
if (source) {
preview.html('<img src="' + source + '" alt="Selected media" style="width:100%;height:100%;object-fit:cover;">');
} else {
preview.html('<i class="fa fa-image fa-2x" style="color:#a7b0b8;"></i>');
}
setProgressShellBackground(source);
}
function markSelectedMediaThumb(value) {
$('.progress-media-select-thumb').removeClass('is-selected');
if (!value) {
return;
}
$('.progress-media-select-thumb').each(function() {
if (($(this).attr('data-media-url') || '') === value) {
$(this).addClass('is-selected');
}
});
}
$(document).off('click.addProgressMediaSelect', '.progress-media-select-thumb').on('click.addProgressMediaSelect', '.progress-media-select-thumb', function() {
var mediaUrl = $(this).attr('data-media-url') || '';
$('#progress-media-gallery-path').val(mediaUrl);
markSelectedMediaThumb(mediaUrl);
$('#progressMediaUpload').val('');
$('input[name="removeProgressMedia"]').prop('checked', false);
if (mediaUrl) {
renderProgressPreview(mediaUrl);
}
$('#progress-media-modal').modal('hide');
});
$(document).off('change.addProgressMediaUpload', '#progressMediaUpload').on('change.addProgressMediaUpload', '#progressMediaUpload', function() {
var file = this.files && this.files[0] ? this.files[0] : null;
if (!file) {
return;
}
$('#progress-media-gallery-path').val('');
markSelectedMediaThumb('');
$('input[name="removeProgressMedia"]').prop('checked', false);
var reader = new FileReader();
reader.onload = function(e) {
renderProgressPreview(e.target.result);
$('#progress-media-modal').modal('hide');
};
reader.readAsDataURL(file);
});
$(document).off('shown.bs.modal.addProgressMediaModal', '#progress-media-modal').on('shown.bs.modal.addProgressMediaModal', '#progress-media-modal', function() {
markSelectedMediaThumb($('#progress-media-gallery-path').val());
});
})();
JS
, \yii\web\View::POS_END);
if ($isInline) {
$cancelPayload = Json::htmlEncode([
'source' => 'animal-inline-editor',
'type' => 'cancel',
'collapseId' => 'progress-add-inline',
]);
$this->registerJs(<<<JS
$(document).on('click', '#progress-inline-add-cancel, #progress-inline-add-cancel-icon', function() {
if (window.parent && window.parent !== window) {
window.parent.postMessage($cancelPayload, '*');
}
});
JS
, \yii\web\View::POS_END);
}
?>