SERP.MvcModules.Product 1.16.9

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
82
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
67
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
56
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
54
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
43
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
39
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
35
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
30
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
19
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
18
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
17
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
16
SERP.MvcModules.Cooperative
SERP.MvcModules.Cooperative
14

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