{{-- Dynamic Elements Rendering --}}
@php
// Normalize elements structure
$elements = data_get($cardSetting, 'elements', []);
if (empty($elements) && is_array($cardSetting)) {
// Backward compatibility for flat structure
$elements = array_filter($cardSetting, function($k) {
return !in_array($k, ['width', 'height', 'bg_type', 'bg_color', 'bg_image', 'layout', 'card', 'status']);
}, ARRAY_FILTER_USE_KEY);
}
// Auto-Deduplicate Logic
// Runs on the final $elements array (whether from 'elements' key or flat structure)
if (!empty($elements)) {
$seen = [];
$deduped = [];
foreach ($elements as $k => $el) {
// Generate a signature for comparison (Data Key + Approx Position)
$dKey = data_get($el, 'data_key', is_string($k) ? $k : 'unknown');
if ($dKey === 'unknown') $dKey = 'txt_'.json_encode($el); // Fallback for pure custom text without key
// Determine if this is a unique field that should strictly not be duplicated (e.g. name, qr, avatar)
// Unless it's a custom text element (starts with txt_) or explicitly 'custom'
$isUniqueField = !str_starts_with($dKey, 'txt_') && $dKey !== 'custom';
if ($isUniqueField) {
// Strict deduplication for fields: Ignore position!
// This fixes "Ghost Elements" where an old element and new element exist for the same field
$sig = $dKey;
} else {
// For custom text or shapes, we trust the ID ($k) to be unique.
// We do NOT want to merge custom elements even if they are in the same position.
// This ensures that if a user places two texts close to each other, both appear.
$sig = $k;
}
if (isset($seen[$sig])) {
// It's a duplicate! Skip it.
continue;
}
$seen[$sig] = true;
$deduped[$k] = $el;
}
// If we actually filtered something, use the filtered list
if (count($deduped) < count($elements)) {
$elements = $deduped;
}
}
@endphp
@foreach($elements as $key => $setting)
@if(data_get($setting, 'visible', false))
@php
// Check if this is new Design (has 'left') or Legacy (has 'x')
$isNewDesign = isset($setting['left']);
$x = data_get($setting, 'x', 0);
$y = data_get($setting, 'y', 0);
$left = data_get($setting, 'left', 0);
$top = data_get($setting, 'top', 0);
$width = data_get($setting, 'width', null);
$height = data_get($setting, 'height', null);
$size = data_get($setting, 'size', 12);
$color = data_get($setting, 'color', '#000000');
$align = data_get($setting, 'align', 'left');
$font = data_get($setting, 'font', 'DejaVu Sans');
$weight = data_get($setting, 'weight', 'normal');
$italic = data_get($setting, 'italic', 'normal');
$posStyle = "";
if ($isNewDesign) {
// New Design: uses px, left/top is top-left corner
$posStyle = "position:absolute; left:{$left}px; top:{$top}px;";
if ($width) $posStyle .= "width:{$width}px;";
if ($height) $posStyle .= "height:{$height}px;";
$posStyle .= "text-align:{$align};";
// Font size in px
$fontSizeUnit = 'px';
} else {
// Legacy: uses mm, x might be center
$posStyle = "position:absolute; left:{$x}mm; top:{$y}mm;";
if ($align === 'center') {
$posStyle .= "transform: translateX(-50%); text-align: center;";
} elseif ($align === 'right') {
$posStyle .= "transform: translateX(-100%); text-align: right;";
} else {
$posStyle .= "text-align: left;";
}
// Font size in pt
$fontSizeUnit = 'pt';
}
@endphp
@if($key === 'avatar' || $key === 'photo' || data_get($setting, 'data_key') === 'avatar' || data_get($setting, 'data_key') === 'photo')
@php
$shape = data_get($setting, 'shape', 'square'); // square, circle
$borderRadius = ($shape === 'circle') ? '50%' : '12px';
// If new design, size might be in width/height
$imgStyle = $posStyle;
if (!$isNewDesign) {
$imgStyle .= "width:{$size}mm; height:{$size}mm;";
}
@endphp
@elseif($key === 'qr_code' || $key === 'qr' || data_get($setting, 'data_key') === 'qr_code' || data_get($setting, 'data_key') === 'qr')
@php
$qrStyle = $posStyle;
if (!$isNewDesign) {
$qrStyle .= "width:{$size}mm; height:{$size}mm;";
}
@endphp
@php
$qrData = $userParticipant->id ?? 0; // Use user ID or unique code
// If ActivityUser has unique code, use it.
if (isset($peserta->uid)) $qrData = $peserta->uid;
elseif (isset($peserta->id)) $qrData = "V:{$activity->id}:{$peserta->id}";
// For QR size, if new design use width, else use size
$qrSizePx = $isNewDesign ? ($width ?? 100) : ($size * 3.78);
$qrSvg = \SimpleSoftwareIO\QrCode\Facades\QrCode::size(round($qrSizePx))->generate($qrData);
$qrBase64 = base64_encode($qrSvg);
@endphp
@else
{{-- Text Elements --}}
@php
$val = '-';
$fieldType = data_get($setting, 'fieldType');
$dataKey = data_get($setting, 'data_key', $key);
$staticText = data_get($setting, 'text');
if ($fieldType === 'custom' && $staticText) {
$val = $staticText;
} elseif ($fieldType === 'email') {
$val = $userParticipant->email ?? '-';
} elseif ($fieldType === 'phone') {
$val = $profileParticipant->no_hp ?? '-';
} elseif ($fieldType === 'institution') {
$val = $profileParticipant->instansi ?? '-';
} elseif ($fieldType === 'province') {
$val = $provinceParticipant ?? '-';
} elseif ($fieldType === 'regency') {
$val = $regencyParticipant ?? '-';
} elseif ($fieldType === 'district') {
$val = $districtParticipant ?? '-';
} elseif ($dataKey === 'title') {
$val = str_replace(["\r\n","\n"], ' ', ($activity->name ?? 'KARTU PESERTA'));
} elseif ($dataKey === 'name') {
$val = $userParticipant->name ?? '-';
} elseif ($dataKey === 'status') {
$isCommittee = $activity->canManageRegistration($userParticipant->id);
$val = $isCommittee ? 'PANITIA' : 'PESERTA';
} elseif ($dataKey === 'role') {
$val = $peserta->role ?? $peserta->position ?? 'Peserta';
} elseif ($dataKey === 'id_number') {
$val = $peserta->participant_number ?? $peserta->id ?? '-';
} elseif (isset($peserta->$dataKey)) {
$val = $peserta->$dataKey;
} elseif (isset($userParticipant->$dataKey)) {
$val = $userParticipant->$dataKey;
} elseif (isset($profileParticipant->$dataKey)) {
$val = $profileParticipant->$dataKey;
} elseif (isset($peserta->custom_data) && is_array($peserta->custom_data) && isset($peserta->custom_data[$dataKey])) {
$val = $peserta->custom_data[$dataKey];
} elseif (isset($profileParticipant->additional_data) && is_array($profileParticipant->additional_data) && isset($profileParticipant->additional_data[$dataKey])) {
$val = $profileParticipant->additional_data[$dataKey];
}
// Handle object values (like relationships)
if (is_object($val)) {
$val = $val->name ?? '-';
}
@endphp
{{ $val }}
@endif
@endif
@endforeach