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
89
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
87
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
63
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
58
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
50
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
45
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
42
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
36
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
30
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
28
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
25
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
23
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
22
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
21
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
20

Version Downloads Last updated
1.16.31 88 05/10/2025
1.16.30 51 04/14/2025
1.16.29 28 04/12/2025
1.16.28 28 04/11/2025
1.16.27 17 04/10/2025
1.16.26 33 03/29/2025
1.16.25 19 03/29/2025
1.16.21 62 03/29/2025
1.16.20 41 02/21/2025
1.16.19 21 02/21/2025
1.16.18 21 02/21/2025
1.16.17 43 02/17/2025
1.16.15 66 02/13/2025
1.16.14 23 02/13/2025
1.16.13 24 02/13/2025
1.16.12 22 02/13/2025
1.16.11 18 02/13/2025
1.16.10 23 02/13/2025
1.16.9 21 02/13/2025
1.16.8 19 02/13/2025
1.16.7 22 02/13/2025
1.16.6 28 02/12/2025
1.16.5 24 02/12/2025
1.16.4 22 02/12/2025
1.16.3 33 02/10/2025
1.16.2 19 02/10/2025
1.16.1 22 02/10/2025
1.15.256 66 01/16/2025
1.15.255 22 01/15/2025
1.15.254 21 01/15/2025
1.15.253 22 01/15/2025
1.15.252 24 01/15/2025
1.15.251 23 01/15/2025
1.15.31 26 02/08/2025
1.15.30 22 02/08/2025
1.15.27 20 02/08/2025
1.15.26 21 02/08/2025
1.15.25 32 01/15/2025