Ajax filter for categories in WordPress

I’m building a site with WordPress. I’ve created a filter with the default category to display the posts. The filter uses checkboxes, so the user can select one or multiple categories.

The issue is, when I select a category it displays all the posts. I’m not sure from where comes the problem, the Ajax handler or the Javascript.

I would also like that when none of the category is selected, it displays all the posts.

The PHP filter:

<?php
if( $terms = get_terms( array( 'taxonomy' => 'category', 'parent' => 0, 'hide_empty' => true ) ) ) :

    echo '
    <form data-ajax-url="'. get_site_url()  .'/wp-admin/admin-ajax.php" method="POST" id="filter" class="js-filter">
        <ul class="js-filter-list">';

            foreach( $terms as $term ) :

                $term_id = $term->term_id;
                $term_name = $term->name;
                $term_slug = $term->slug;

                $term_color = get_term_meta( $term_id, 'post-category-settings__color', true );

                echo '
                <li class="js-filter-item js-filter-term" data-slug="'. esc_attr( $term_slug ) .'">
                    <input type="checkbox" class="c-filter__check" id="' . esc_attr($term_id) . '" name="' . esc_attr($term_id) . '" />
                    <label class="semi-medium" for="' . esc_attr($term_id) . '"><span></span>' . esc_html($term_name) . '</label>
                </li>';
            endforeach;

    echo '
        </ul>
        <input type="hidden" name="action" value="filterpost">
    </form>';
endif;
?>

<div class="js-container"></div>

The JS:

if (document.querySelector('.js-filter')) {
    const ajax_url = document.querySelector(".js-filter").dataset.ajaxUrl;
    let filterBtn = document.querySelectorAll('.js-filter-term');

    var i;
    for( i = 0; i < filterBtn.length; i++ ){
        filterBtn[i].addEventListener('change', function(){

            const containerTerm = document.querySelector(".js-container");
            const data = new FormData();

            let term_slug = this.dataset.slug;

            data.append( 'action', 'filterpost' );
            data.append( 'category', term_slug );

            fetch(ajax_url, {
            method: "POST",
            body: data
            })
            .then((response) => response.text())
            .then((data) => {
            if (data) {
                containerTerm.innerHTML=data;
            }
            })
            .catch((error) => {

            });
        });
    };
}

The AJAX handler:

<?php
function site_filter_post() {

    if( $terms = get_terms( array( 'taxonomy' => 'category' ) ) ) :
        $terms_list = array();

        foreach( $terms as $term ) {
        if( isset( $_POST[$term->term_id ] ) && $_POST[$term->term_id] == 'on' )
         $terms_list[] = $term->slug;
        }
    endif;

    $tax_query = array( 'relation' => 'AND' );
  
    if ( ! empty( $terms_list ) ) {
        $tax_query[] = array(
            array(
            'taxonomy'      => 'category',
            'field'         => 'slug',
            'terms'         => $terms_list,
            )
        );
    }
  
    $args = array(
        'post_type'         => 'post',
        'posts_per_page'    => -1,
        'post_status'       => 'publish',
        'orderby'           => 'date',
        'tax_query' => array(
            $tax_query
        )
    );

    $query = new WP_Query( $args );
  
    if($query->have_posts()) {

        while($query->have_posts()) : $query->the_post();

            get_template_part( 'template-parts/content', 'archive' );
  
        endwhile;
  
    } else {

        echo 'No result.';

    }
  
    exit;
}
add_action('wp_ajax_filterpost', 'site_filter_post');
add_action('wp_ajax_nopriv_filterpost', 'site_filter_post');
?>

Thank you.