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
133
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
95
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
70
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
64
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
57
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
50
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
47
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
42
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
35
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
34
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
33
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
31
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
29
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
28
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
27
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
26

Version Downloads Last updated
1.16.31 140 05/10/2025
1.16.30 58 04/14/2025
1.16.29 32 04/12/2025
1.16.28 39 04/11/2025
1.16.27 26 04/10/2025
1.16.26 39 03/29/2025
1.16.25 23 03/29/2025
1.16.21 68 03/29/2025
1.16.20 48 02/21/2025
1.16.19 26 02/21/2025
1.16.18 29 02/21/2025
1.16.17 48 02/17/2025
1.16.15 72 02/13/2025
1.16.14 28 02/13/2025
1.16.13 28 02/13/2025
1.16.12 30 02/13/2025
1.16.11 23 02/13/2025
1.16.10 29 02/13/2025
1.16.9 26 02/13/2025
1.16.8 26 02/13/2025
1.16.7 26 02/13/2025
1.16.6 31 02/12/2025
1.16.5 31 02/12/2025
1.16.4 29 02/12/2025
1.16.3 39 02/10/2025
1.16.2 27 02/10/2025
1.16.1 30 02/10/2025
1.15.256 73 01/16/2025
1.15.255 28 01/15/2025
1.15.254 27 01/15/2025
1.15.253 28 01/15/2025
1.15.252 31 01/15/2025
1.15.251 27 01/15/2025
1.15.31 32 02/08/2025
1.15.30 27 02/08/2025
1.15.27 29 02/08/2025
1.15.26 26 02/08/2025
1.15.25 40 01/15/2025