Debug School

rakesh kumar
rakesh kumar

Posted on

How Alpine js can be used to create a more dynamic and user-friendly interface

HTML Structure

<div class="row" id="resultContainer" style="margin-top: 2%;" x-data="orderData">
    <div class="col-lg-12 col-md-12 col-sm-12 col-12">
        <div class="col-md-12 col-lg-12">
            <div class="card" style="padding: 27px;">
                <div id="resultContent">
                    <template x-for="item in orders" :key="item.order_id">
                        <div class="card">
                            <div class="card-header row">
                                <div class="card-body row">
                                    <div class="col-md-6">
                                        <p class="black-text"><b>Order Id:</b> <span x-text="item.order_id"></span></p>
                                        <p class="black-text"><b>Cart Id: </b> <span x-text="item.cart_id"></span></p>
                                        <p class="black-text"><b>Payment date: </b> <span x-text="item.payment_date"></span></p>
                                    </div>
                                    <div class="col-md-6">
                                        <p class="black-text"><b>Amount:</b> <span x-text="item.amount"></span></p>
                                        <p class="black-text"><b>Payment ID:</b> <span x-text="item.payment_id"></span></p>
                                        <p class="black-text"><b>Payment status: </b> <span x-text="item.payment_status"></span></p>
                                    </div>
                                </div>
                            </div>
                            <div class="card-body row">
                                <div class="left-content col-md-10">
                                    <div class="black-text">
                                        <b>Product Id:</b> <span x-text="item.product_id"></span> |
                                        <b>Influencer email:</b> <span x-text="item.influencer_email"></span> |
                                        <b>Influencer name: </b> <span x-text="item.influencer_name"></span>
                                    </div>
                                    <div class="order-container">
                                        <template x-for="(status, index) in getStatuses(item)" :key="index">
                                            <div>
                                                <div style="color: black; font-weight: bold; margin-top: 20px;" x-text="status.label"></div>
                                                <div class="circle" :class="{'highlighted': status.highlighted}" :style="status.style">
                                                    <i class="fas fa-check" style="color: white;" x-show="status.showCheck"></i>
                                                    <i class="fas fa-times" style="color: white;" x-show="status.showTimes"></i>
                                                </div>
                                                <div class="arrow" :class="{'arrowhighlight': status.arrowHighlight}" :style="status.arrowStyle"></div>
                                            </div>
                                        </template>
                                    </div>
                                    <div class="order-container">
                                        <template x-for="date in getOrderDates(item)" :key="date">
                                            <div style="color: black; font-weight: bold; margin-top: 20px;" x-text="date"></div>
                                        </template>
                                    </div>
                                </div>
                                <div class="right-content col-md-2" style="margin-top: 80px;">
                                    <div class="nested-col">
                                        <button class="btn btn-primary tasks-button" style="width: 150px;" @click="updateTask(item.order_id, item.product_id)">Update Task</button>
                                        <div style="margin-top: 5px;"></div>
                                        <button class="btn btn-primary tasks-lock" style="width: 150px;" @click="lockTask(item.order_id, item.product_id)">Task Lock</button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </template>
                </div>
                <div class="card-body" id="paginationContainer">
                    <!-- Pagination controls will be added here -->
                </div>
            </div>
        </div>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Root Container

(<div class="row" id="resultContainer" style="margin-top: 2%;" x-data="orderData">):

Enter fullscreen mode Exit fullscreen mode
  1. This is the root container for the order data.
  2. x-data="orderData" initializes Alpine.js with the orderData function, which contains the data and methods for this component . Main Card Container
 (<div class="col-lg-12 col-md-12 col-sm-12 col-12">):
Enter fullscreen mode Exit fullscreen mode
  • This is a wrapper for the card elements, ensuring the content spans the entire width of the container . Card Element
 (<div class="card" style="padding: 27px;">):
Enter fullscreen mode Exit fullscreen mode
  • This card element contains the main structure for displaying order details . Order List
(<template x-for="item in orders" :key="item.order_id">):
Enter fullscreen mode Exit fullscreen mode
  1. This template iterates over the orders array and generates a card for each order.
  2. x-for directive is used to loop through the orders array, and :key ensures each item has a unique key

Order Details Header

(<div class="card-header row">):
Enter fullscreen mode Exit fullscreen mode

This section displays the basic order details like Order ID, Cart ID, Payment date, Amount, Payment ID, and Payment status.
Order Details Body

 (<div class="card-body row">):
Enter fullscreen mode Exit fullscreen mode

This section displays additional details including Product ID, Influencer email, and Influencer name.
It also includes the order status and dates.
Order Status

(<div class="order-container">):
Enter fullscreen mode Exit fullscreen mode
  1. This section uses x-for to loop through the statuses and display each status with corresponding icons and styles.
  2. It uses the getStatuses method to determine the statuses and their styles . Order Dates
(<div class="order-container">):
Enter fullscreen mode Exit fullscreen mode
  1. This section uses x-for to loop through the dates and display them.
  2. It uses the getOrderDates method to format and display the dates . Action Buttons
(<div class="right-content col-md-2" style="margin-top: 80px;">):
Enter fullscreen mode Exit fullscreen mode
  1. This section contains buttons for updating and locking tasks.
  2. The @click directive binds the buttons to the updateTask and lockTask methods

Alpine.js Data and Methods

<script>
    function orderData() {
        return {
            orders: [
                {
                    order_id: 'ORD-1709629982-4360',
                    cart_id: 'CART-RZUn-18',
                    payment_date: '2024-03-05',
                    amount: '1.1',
                    payment_id: 'PAYID-ORDS92196781',
                    payment_status: 'approved',
                    product_id: 178,
                    influencer_email: 'anuprajak.cotocus@gmail.com',
                    influencer_name: 'anup-rajak',
                    tasklockstatusValue: 'place',
                    statusvalue: 'approved',
                    cartsdate: '2024-03-05',
                    created_at: '2024-03-05',
                    mytaskcreated: '2024-03-05',
                    mytaskdates: '2024-03-07',
                    mystatusdate: '2024-03-29'
                },
                {
                    order_id: 'ORD-1709809433-7885',
                    cart_id: 'CART-Rsc1-18',
                    payment_date: '2024-03-07',
                    amount: '1.1',
                    payment_id: 'PAYID-ORDS73341012',
                    payment_status: 'approved',
                    product_id: 179,
                    influencer_email: 'anotheremail@example.com',
                    influencer_name: 'another-name',
                    tasklockstatusValue: 'locked',
                    statusvalue: 'not approved',
                    cartsdate: '2024-03-07',
                    created_at: '2024-03-07',
                    mytaskcreated: '2024-03-07',
                    mytaskdates: '2024-03-07',
                    mystatusdate: '2024-03-29'
                }
                // Add more orders as needed
            ],
            updateTask(orderId, productId) {
                console.log(`Update task for Order ID: ${orderId}, Product ID: ${productId}`);
                // Add your update task logic here
            },
            lockTask(orderId, productId) {
                console.log(`Lock task for Order ID: ${orderId}, Product ID: ${productId}`);
                // Add your lock task logic here
            },
            getStatuses(item) {
                let orderStatuses = ['Cart Added', 'Order Created', 'Task Submitted', 'Awaiting Task', 'Task Approved', 'Task Completed'];
                let loopLength = (item.tasklockstatusValue && item.tasklockstatusValue.includes('locked')) ? orderStatuses.length - 2 :
                    (item.statusvalue && item.statusvalue.includes('not approved')) ? orderStatuses.length - 1 :
                    (item.statusvalue && item.statusvalue.includes('Reject')) ? orderStatuses.length - 1 : orderStatuses.length;

                return orderStatuses.slice(0, loopLength).map((status, index) => {
                    let result = { label: status, highlighted: index <= 3, style: '', showCheck: index <= 3, showTimes: false, arrowHighlight: index < 3, arrowStyle: '' };

                    if (index === 3 && item.tasklockstatusValue === 'place') {
                        result.label = 'Task Locked';
                    } else if (index === 4) {
                        if (item.tasklockstatusValue === 'locked') {
                            result.style = 'background-color:#ccc;';
                        } else {
                            result.label = item.statusvalue === 'not approved' ? 'Not Approved' :
                                (item.statusvalue === 'Reject' ? 'Rejected' : 'Approved');
                            result.showTimes = item.statusvalue === 'Reject';
                            result.style = item.statusvalue === 'not approved' ? 'background-color:#ccc;' :
                                (item.statusvalue === 'Reject' ? 'background-color:red;' : 'background-color:#15e715;');
                        }
                    } else if (index === 5) {
                        result.label = item.statusvalue === 'completed' ? 'completed' :
                            (item.statusvalue === 'onhold' ? 'onhold' :
                                (item.statusvalue === 'InProgress' ? 'InProgress' :
                                    (item.statusvalue === 'Todo' ? 'Todo' : 'Todo')));
                        result.showCheck = item.statusvalue === 'completed';
                        result.style = item.statusvalue === 'completed' ? 'background-color:#15e715;' : 'background-color:#ccc;';
                    }

                    return result;
                });
            },
            getOrderDates(item) {
                return [
                    new Date(item.cartsdate).toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' }),
                    new Date(item.created_at).toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' }),
                    new Date(item.mytaskcreated).toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' }),
                    item.mytaskdates === '01/01/1970' ? 'Pending' : new Date(item.mytaskdates).toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' }),
                    item.mystatusdate === '01/01/1970' ? 'Pending' : new Date(item.mystatusdate).toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' })
                ];
            }
        }
    }
</script>
Enter fullscreen mode Exit fullscreen mode

orderData Function:

  1. Contains the orders array with detailed information about each order.
  2. Includes methods updateTask, lockTask, getStatuses, and getOrderDates
    .
    updateTask Method:

  3. Logs the order and product IDs for updating the task.

  4. This method should contain the logic to handle task updates
    .
    lockTask Method:

  5. Logs the order and product IDs for locking the task.

  6. This method should contain the logic to handle task locking
    .
    getStatuses Method:

  7. Generates an array of status objects for the given order.

  8. Each status object contains label, highlighted, style, showCheck, showTimes, arrowHighlight, and arrowStyle properties.

  9. Logic to handle different conditions and styles based on tasklockstatusValue and statusvalue
    .
    getOrderDates Method:

  10. Formats and returns an array of dates for the given order.

  11. Converts timestamps to readable date strings.

  12. By using Alpine.js, this code leverages reactive data binding and conditional rendering to create a dynamic and interactive order management interface

Image description

Top comments (0)