SERP.MvcModules.Product 1.16.31

Faq List

NhĂșng FaQs component

@await Component.InvokeAsync(nameof(FaQsLazyListComponent), new FaQsViewModel
{
    Type = "user-manual",
    ApplicationId = Guid.Parse("514C5642-5F4C-534E-5F53-545454542E00"),
    PickRandom = true,
    ViewType = "modal",
    // ViewPath = "~/Views/PortalModules/ProductDetail/SubProductDetail/ProductDetailTab/ProductReview.cshtml",
})
@await Component.InvokeAsync(nameof(FaQsLazyListComponent), new FaQsViewModel
{
    ApplicationId = Guid.Parse("514C5642-5F4C-534E-5F53-545454542E00"),
    PickRandom = true,
    PageSize = 7,
    Type = "tip",
    ViewType = "tip",
    // ViewPath = "~/Views/PortalModules/ProductDetail/SubProductDetail/ProductDetailTab/ProductReview.cshtml",
})
    ```

## Lazy list FaQs 

### Tooltips (jQuery)

Refer js - could be copied and add to site.js
``` javascript
function faqFetchAndShowToast(appId, pickRandom=true, type='tip')  {
    $.ajax({
      url: `api/v1/bff/faqs2?applicationId=${appId}&size=1&pickRandom=${pickRandom}&type=${type}`,
      method: 'GET',
      success: function(res) {
        if (res && res.data && res.data.content && res.data.content.length > 0) {
          let content = res.data.content[0];
        
          // Display the FAQ item in a toastr
          toastr.success(content.answer, content.question, {
            timeOut: 10000, // Show toastr for 10 seconds
            positionClass: 'toast-top-right', // Position of the toastr
            closeButton: true, // Show close button
            progressBar: true // Show progress bar
          });
        } else {
          console.error('No FAQ data available');
        }
      },
      error: function() {
        console.error('Error fetching data from the server.');
      }
    });
  }

Usage

$(document).ready(function() {
    setInterval(function(){
      faqFetchAndShowToast('@Model.ApplicationId', @Model.PickRandom.ToString().ToLower(), '@Model.Type');
    }, 30000); // Repeated call every 30 seconds
      
    console.log(`Use this method for testing: faqFetchAndShowToast('@Model.ApplicationId', @Model.PickRandom.ToString().ToLower(), '@Model.Type');`)
  });

Those styles should be copied to site.css

    @@media (min-width: 576px) {
        #faqModal .modal-dialog {
            max-width: 750px;
            margin: 1.75rem auto;
        }
    }

    #faqModal .faq__question {
        font-weight: bold;
        color: #f12a20;
    }

    #faqModal .modal-content {
        border-radius: 15px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
    }

    #faqModal .modal-header {
        background-color: #F3F4F6;
        color: #434343;
        border-radius: 13px 13px 0 0;
    }

    #faqModal .modal-footer {
        background-color: #f1f1f1;
    }

    #faqModal .close {
        color: #434343;
        opacity: 1;font-size: 2rem;
    }

    #faqCarousel.carousel .carousel-control-prev, #faqCarousel.carousel .carousel-control-next {
        color:  #434343; font-size: 3rem;
    }
    #faqCarousel .carousel-indicators li {
        background-color: #434343;
    }
    #faqCarousel .carousel-item img {
        max-width: 100%;
        object-fit: cover;
    }

// Those script should be copied to site.js

    function faqsShouldShowModal() {
        const lastShown = getCookie('faqLastModalShown');
        if (!lastShown) return true; // If cookie doesn't exist, show the modal

        const lastDate = new Date(lastShown);
        const currentDate = new Date();
        const diffTime = Math.abs(currentDate - lastDate); // Get the difference in milliseconds
        const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); // Convert to days

        return diffDays >= 3; // Return true if 3 or more days have passed
    }

    // Function to show the modal
    function faqShowModal() {
        $('#faqModal').modal('show'); // Bootstrap method to show modal
        setCookie('faqLastModalShown', new Date().toISOString(), 3); // Update the cookie to store current date
    }

    function faqRetrieveModalData(appId, pageSize = 7, pickRandom=true, type='user-manual') {
        // Fetch slide content via AJAX
        $.ajax({
            url: `api/v1/bff/faqs2?applicationId=${appId}&size=${pageSize}&pickRandom=${pickRandom}&type=${type}`,
            method: 'GET',
            success: function(res) {
                if (res && res.data && res.data.content && res.data.content.length > 0) {
                    //console.log(res);
                    // Clear previous carousel content
                    $('#faqCarouselContent').empty();
                    $('#faqCarouselIndicators').empty();

                    let content = res.data.content;
                    // Loop through the data and create carousel items
                    content.forEach(function(item, index) {
                        let activeClass = index === 0 ? 'active' : '';  // Make the first item active
                        let carouselItem = `
              <div class="carousel-item ${activeClass}">
                    <div class="faq__question">${item.question}</div>
                    <div class="faq__answer">${item.answer}</div> 
              </div>`;
                        $('#faqCarouselContent').append(carouselItem);

                        let carouselIndicator = `<li data-target="#faqCarousel" data-slide-to="${index}" class="${activeClass}"></li>`;
                        $('#faqCarouselIndicators').append(carouselIndicator);
                    });

                    faqShowModal();
                }
            },
            error: function() {
                console.error('Error fetching data from the server.');
            }
        });
    }

Usage

$(document).ready(function() {
    // Only show the modal if 3 days have passed
    if (faqsShouldShowModal()){
        setTimeout(function() {
            faqRetrieveModalData('@Model.ApplicationId', @Model.PageSize, @Model.PickRandom.ToString().ToLower(), '@Model.Type');
        }, 3000); // Show after 3 seconds
    }

    console.log(`Use this method for testing: faqRetrieveModalData('@Model.ApplicationId', @Model.PageSize, @Model.PickRandom.ToString().ToLower(), '@Model.Type');`)
});

Showing the top 20 packages that depend on SERP.MvcModules.Product.

Packages Downloads
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
145
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
99
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
75
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
70
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
62
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
53
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
46
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
38
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
37
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
36
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
35
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
34
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
32

Version Downloads Last updated
1.16.31 155 05/10/2025
1.16.30 63 04/14/2025
1.16.29 38 04/12/2025
1.16.28 45 04/11/2025
1.16.27 35 04/10/2025
1.16.26 46 03/29/2025
1.16.25 30 03/29/2025
1.16.21 75 03/29/2025
1.16.20 53 02/21/2025
1.16.19 31 02/21/2025
1.16.18 34 02/21/2025
1.16.17 54 02/17/2025
1.16.15 77 02/13/2025
1.16.14 33 02/13/2025
1.16.13 33 02/13/2025
1.16.12 36 02/13/2025
1.16.11 30 02/13/2025
1.16.10 36 02/13/2025
1.16.9 32 02/13/2025
1.16.8 34 02/13/2025
1.16.7 31 02/13/2025
1.16.6 38 02/12/2025
1.16.5 39 02/12/2025
1.16.4 35 02/12/2025
1.16.3 45 02/10/2025
1.16.2 32 02/10/2025
1.16.1 36 02/10/2025
1.15.256 80 01/16/2025
1.15.255 37 01/15/2025
1.15.254 30 01/15/2025
1.15.253 32 01/15/2025
1.15.252 35 01/15/2025
1.15.251 31 01/15/2025
1.15.31 38 02/08/2025
1.15.30 34 02/08/2025
1.15.27 35 02/08/2025
1.15.26 33 02/08/2025
1.15.25 45 01/15/2025