From 04961a55929017f77ee6801d2b7ada4c05689821 Mon Sep 17 00:00:00 2001
From: it-fixcomart <it@fixcomart.co.id>
Date: Thu, 31 Jul 2025 15:55:05 +0700
Subject: <hafid> fix repeat order

---
 src/lib/transaction/components/Transactions.jsx | 461 +++++++++++++-----------
 1 file changed, 258 insertions(+), 203 deletions(-)

(limited to 'src/lib/transaction/components/Transactions.jsx')

diff --git a/src/lib/transaction/components/Transactions.jsx b/src/lib/transaction/components/Transactions.jsx
index c4651119..acb925da 100644
--- a/src/lib/transaction/components/Transactions.jsx
+++ b/src/lib/transaction/components/Transactions.jsx
@@ -1,5 +1,5 @@
 import { useRouter } from 'next/router';
-import { useEffect, useState } from 'react';
+import { useEffect, useState, useRef  } from 'react';
 import { toast } from 'react-hot-toast';
 import {
   EllipsisVerticalIcon,
@@ -34,7 +34,10 @@ import Image from '@/core/components/elements/Image/Image';
 import { upsertUserCart } from '~/services/cart';
 import { useProductCartContext } from '@/contexts/ProductCartContext';
 import { Swiper, SwiperSlide } from 'swiper/react';
+import { Navigation } from 'swiper';
 import 'swiper/css';
+import 'swiper/css/navigation';
+import { Calendar } from 'lucide-react';
 import DatePicker from 'react-datepicker';
 import 'react-datepicker/dist/react-datepicker.css';
 import { DateRangePicker } from 'react-date-range';
@@ -45,6 +48,7 @@ import { Popover } from '@headlessui/react';
 const Transactions = ({ context = '' }) => {
   const auth = useAuth();
   const router = useRouter();
+  const swiperRef = useRef(null);
   const {
     q = '',
     page = 1,
@@ -80,11 +84,12 @@ const Transactions = ({ context = '' }) => {
   const [isOpenCalender, setIsOpenCalender] = useState(false);
   const [cachedAllData, setCachedAllData] = useState(null); // Simpan data "All"
   const [currentData, setCurrentData] = useState([]);     // Data yang ditampilkan
+  const calendarRef = useRef(null);
+  const [isDateSelected, setIsDateSelected] = useState(false);
 
   const parseDate = (date) => {
-    if (null || 'null') return null;
-    if (!date) return null;
-    if (date instanceof Date) return date; // Jika sudah Date, langsung return
+    if (!date || date === 'null') return null;
+    if (date instanceof Date) return date;
     const [day, month, year] = date.split('/').map(Number);
     return new Date(year, month - 1, day);
   };
@@ -106,7 +111,7 @@ const Transactions = ({ context = '' }) => {
     sort: sortNew,
     startDate: state[0].startDate
       ? state[0].startDate.toLocaleDateString('id-ID')
-      : state[0].startDate,
+      : null,
     endDate: state[0]?.endDate?.toLocaleDateString('id-ID'),
     site:
       siteFilter || (auth?.webRole === null && auth?.site ? auth.site : null),
@@ -114,8 +119,9 @@ const Transactions = ({ context = '' }) => {
   const statuses = [
     { id: 'all', label: 'Semua' },
     { id: 'quotation', label: 'Pending Quotation' },
-    { id: 'diterima', label: 'Pesanan Diterima' },
     { id: 'diproses', label: 'Pesanan Diproses' },
+    { id: 'dikemas', label: 'Pesanan Dikemas' },
+    { id: 'partial', label: 'Dikirim Sebagian' },
     { id: 'dikirim', label: 'Pesanan Dikirim' },
     { id: 'selesai', label: 'Pesanan Selesai' },
     { id: 'cancel', label: 'Pesanan Dibatalkan' },
@@ -302,6 +308,22 @@ const Transactions = ({ context = '' }) => {
     }
   };
 
+  useEffect(() => {
+    const handleClickOutside = (event) => {
+      if (
+        calendarRef.current &&
+        !calendarRef.current.contains(event.target)
+      ) {
+        setIsOpenCalender(false);
+      }
+    };
+
+    document.addEventListener("mousedown", handleClickOutside);
+    return () => {
+      document.removeEventListener("mousedown", handleClickOutside);
+    };
+  }, []);
+
   const startItem = 1 + (pageNew - 1) * limitNew;
   const endItem = Math.min(
     limitNew * pageNew,
@@ -438,82 +460,82 @@ const Transactions = ({ context = '' }) => {
                 </option>
               ))}
             </select>
-            <div className='relative w-full text-xs'>
-              <div
-                className='border border-gray-300 rounded-lg bg-white shadow-sm focus:outline-none focus:ring-2 focus:ring-red-500 w-full px-2 py-1 flex items-center justify-between cursor-pointer'
-                onClick={() => setIsOpenCalender(true)}
-              >
-                <span className='text-nowrap px-1 truncate'>
-                  {state[0]?.startDate
-                    ? `${state[0].startDate.toLocaleDateString()} - ${state[0].endDate.toLocaleDateString()}`
-                    : 'Semua Tanggal'}
-                </span>
-              </div>
-
-              {isOpenCalender && (
-                <div className='fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50'>
-                  <div className='calendar-container bg-white shadow-lg border rounded-lg p-4  w-full'>
-                    <DateRangePicker
-                      onChange={(item) => setState([item.selection])}
-                      showSelectionPreview={true}
-                      maxDate={new Date()}
-                      moveRangeOnFirstSelection={false}
-                      months={1}
-                      ranges={state}
-                      direction='horizontal'
-                      className='w-full'
-                    />
-                    <style>{`
-                      /* Atur container agar menjadi column */
-                      .rdrCalendarWrapper {
-                        display: flex;
-                        flex-direction: column;
-                      }
-                      .rdrDateRangePickerWrapper  {
-                        display: flex;
-                        flex-direction: column;
-                      }
-
-                      /* Pindahkan rdrStaticRanges ke atas */
-                      .rdrDefinedRangesWrapper {
-                        order: -1;
-                        width: fit-content;
-                      }
-                      .rdrStaticRanges {
-                        flex-direction: row;
-                        margin-right: 2px;
-                      }
-
-                      /* Sembunyikan bagian input manual */
-                      .rdrInputRanges {
-                        display: none !important;
-                      }
-
-                      .rdrStaticRangeLabel {
-                        padding: 10px 10px;
-                      }
-                      .rdrMonth {
-                        width: -moz-available;
-                      }
-                    `}</style>
-                    <div className='flex flex-row justify-end gap-3 mt-2'>
-                      <button
-                        className='px-4 py-1 bg-gray-500 text-white rounded'
-                        onClick={() => setIsOpenCalender(false)}
-                      >
-                        Done
-                      </button>
-                      <button
-                        className='px-4 py-1 bg-red-500 text-white rounded'
-                        onClick={handleReset}
-                      >
-                        Reset
-                      </button>
-                    </div>
+            <div ref={calendarRef} className="relative inline-block">
+                <button
+                  type='button'
+                  className='p-2 w-auto h-auto cursor-pointer hover:bg-gray-100 rounded transition duration-150 ease-in-out flex items-center justify-center'
+                  onClick={() => setIsOpenCalender((prev) => !prev)}
+                >
+                  <span className='text-nowrap px-1 truncate flex items-center gap-1'>
+                      {state[0]?.startDate ? (
+                        `${state[0].startDate.toLocaleDateString()} - ${state[0].endDate.toLocaleDateString()}`
+                      ) : (
+                        <Calendar size={16} className="text-gray-500" />
+                      )}
+                  </span>
+                </button>
+                {isOpenCalender && (
+                <div className='absolute right-1 mt-2 bg-white p-4 rounded shadow-lg z-50'>
+                  {/* Tombol silang di sudut kanan atas */}
+                  <button
+                    onClick={() => setIsOpenCalender(false)}
+                    className='absolute top-2 right-2 text-gray-600 hover:text-black text-xl font-bold'
+                  >
+                    &times;
+                  </button>
+                  <DateRangePicker
+                    onChange={(item) => setState([item.selection])}
+                    showSelectionPreview={false}
+                    maxDate={new Date()}
+                    moveRangeOnFirstSelection={false}
+                    months={1}
+                    ranges={state}
+                    className='w-full'
+                  />
+                  <style>{`
+                    /* Atur container agar menjadi column */
+                    .rdrCalendarWrapper {
+                      display: flex;
+                      flex-direction: column;
+                    }
+                    .rdrDateRangePickerWrapper  {
+                      display: flex;
+                      flex-direction: column;
+                    }
+
+                    /* Pindahkan rdrStaticRanges ke atas */
+                    .rdrDefinedRangesWrapper {
+                      order: -1;
+                      width: fit-content;
+                    }
+                    .rdrStaticRanges {
+                      flex-direction: row;
+                      margin-right: 2px;
+                    }
+
+                    /* Sembunyikan bagian input manual */
+                    .rdrInputRanges {
+                      display: none !important;
+                    }
+
+                    .rdrStaticRangeLabel {
+                      padding: 10px 10px;
+                    }
+                    .rdrMonth {
+                      width: -moz-available;
+                    }
+                  `}</style>
+                  <div className='flex flex-row justify-end gap-3 mt-2'>
+                    <button
+                      className='px-4 py-1 bg-red-500 text-white rounded'
+                      onClick={handleReset}
+                    >
+                      Reset
+                    </button>
                   </div>
                 </div>
-              )}
-            </div>
+                )}
+              </div>
             {/* <div className='border border-gray-300 rounded-lg px-1 py-1 bg-white shadow-sm focus:outline-none focus:ring-2 focus:ring-red-500 text-xs'>
               <DatePicker
                 closeOnScroll={(e) => e.target === document}
@@ -643,7 +665,7 @@ const Transactions = ({ context = '' }) => {
                       {saleOrder.products?.length > 1 && (
                         <div className='flex flex-row gap-1 justify-start items-center'>
                           {saleOrder.products
-                            .slice(1, 6)
+                            .slice(1, 4)
                             .map((product, index) => (
                               <Image
                                 key={index} // Tambahkan key untuk setiap elemen dalam map()
@@ -652,16 +674,21 @@ const Transactions = ({ context = '' }) => {
                                 className='object-contain object-center border border-gray_r-6 h-8 w-8 rounded-md'
                               />
                             ))}
-                          <Link
-                            href={`${router.pathname}/${saleOrder?.id}`}
-                            className=' text-red-500 text-nowrap'
-                          >
-                            {saleOrder.products?.length > 6
-                              ? 'Lihat ' +
-                                (saleOrder.products?.length - 6) +
-                                ' produk lainnya'
-                              : 'Lihat semua produk'}
-                          </Link>
+                          {saleOrder.products.length > 4 ? (
+                              <Link
+                                href={`${router.pathname}/${saleOrder?.id}`}
+                                className='text-red-500 text-nowrap'
+                              >
+                                +{saleOrder.products.length - 4} lihat semua produk
+                              </Link>
+                            ) : (
+                              <Link
+                                href={`${router.pathname}/${saleOrder?.id}`}
+                                className='text-red-500 text-nowrap'
+                              >
+                                Lihat semua produk
+                              </Link>
+                            )}
                         </div>
                       )}
                     </div>
@@ -880,33 +907,60 @@ const Transactions = ({ context = '' }) => {
                 </div>
               </div>
             </div>
-            <div className='flex flex-col gap-y-2  border rounded-lg mb-2'>
+            <div className='flex flex-col gap-y-2  border rounded-lg mb-2 w-full'>
               <div className='p-2'>
                 <div className='flex items-center space-x-3'>
                   <span className='text-base font-semibold text-gray-600'>
                     Status
                   </span>
-                  <Swiper
-                    spaceBetween={10}
-                    slidesPerView={5.8}
-                    className='w-full h-8'
-                  >
-                    {statuses.map((status) => (
-                      <SwiperSlide key={status.id} className='w-auto'>
-                        <button
-                          className={`px-4 py-1 text-sm font-medium border rounded-lg transition whitespace-nowrap min-w-40
-                  ${
-                    statusNew === status.id
-                      ? 'border-red-500 text-red-500 bg-white'
-                      : 'border-gray-300 text-gray-400 bg-gray-100 hover:bg-gray-200'
-                  }`}
-                          onClick={() => handleStatusChange(status.id)}
+                  <div className="relative w-full overflow-hidden">
+                    {/* Container flex: tombol prev - swiper - tombol next */}
+                    <div className="flex items-center space-x-2">
+                      
+                      {/* Prev */}
+                      <button className="custom-prev w-8 h-8 flex-shrink-0 flex items-center justify-center bg-white border rounded-full shadow z-1">
+                        <svg className="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
+                        </svg>
+                      </button>
+
+                      {/* Swiper container scrollable */}
+                      <div className="w-full overflow-hidden">
+                        <Swiper
+                          spaceBetween={10}
+                          slidesPerView="auto"
+                          className="status-swiper"
+                          modules={[Navigation]}
+                          navigation={{
+                            nextEl: '.custom-next',
+                            prevEl: '.custom-prev',
+                          }}
                         >
-                          {status.label}
-                        </button>
-                      </SwiperSlide>
-                    ))}
-                  </Swiper>
+                          {statuses.map((status) => (
+                            <SwiperSlide key={status.id} className="!w-auto">
+                              <button
+                                className={`px-4 py-1 text-sm font-medium border rounded-lg transition whitespace-nowrap
+                                  ${statusNew === status.id
+                                    ? 'border-red-500 text-red-500 bg-white'
+                                    : 'border-gray-300 text-gray-400 bg-gray-100 hover:bg-gray-200'
+                                  }`}
+                                onClick={() => handleStatusChange(status.id)}
+                              >
+                                {status.label}
+                              </button>
+                            </SwiperSlide>
+                          ))}
+                        </Swiper>
+                      </div>
+
+                      {/* Next */}
+                      <button className="custom-next w-8 h-8 flex-shrink-0 flex items-center justify-center bg-white border rounded-full shadow z-10">
+                        <svg className="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
+                        </svg>
+                      </button>
+                    </div>
+                  </div>
                 </div>
               </div>
               <div className='flex flex-row items-center justify-between mb-2 p-2'>
@@ -944,86 +998,6 @@ const Transactions = ({ context = '' }) => {
                     </button>
                   </form>
                 </div>
-                <div className='flex flex-col gap-2 pb-2'>
-                  <button
-                    type='button'
-                    className='form-input btn py-4 mt-1 cursor-pointer hover:bg-gray-100 rounded transition duration-150 ease-in-out text-left w-full'
-                    onClick={() => setIsOpenCalender(true)}
-                  >
-                    <span className='text-nowrap px-1 truncate'>
-                      {state[0]?.startDate
-                        ? `${state[0].startDate.toLocaleDateString()} - ${state[0].endDate.toLocaleDateString()}`
-                        : 'Filter By Tanggal'}
-                    </span>
-                  </button>
-                  {isOpenCalender && (
-                  <div className='absolute mt-2 bg-white p-4 rounded shadow-lg'>
-                    {/* Tombol silang di sudut kanan atas */}
-                    <button
-                      onClick={() => setIsOpenCalender(false)}
-                      className='absolute top-2 right-2 text-gray-600 hover:text-black text-xl font-bold'
-                    >
-                      &times;
-                    </button>
-                    <DateRangePicker
-                      onChange={(item) => setState([item.selection])}
-                      showSelectionPreview={true}
-                      maxDate={new Date()}
-                      moveRangeOnFirstSelection={false}
-                      months={1}
-                      ranges={state}
-                      className='w-full'
-                    />
-                    <style>{`
-                      /* Atur container agar menjadi column */
-                      .rdrCalendarWrapper {
-                        display: flex;
-                        flex-direction: column;
-                      }
-                      .rdrDateRangePickerWrapper  {
-                        display: flex;
-                        flex-direction: column;
-                      }
-
-                      /* Pindahkan rdrStaticRanges ke atas */
-                      .rdrDefinedRangesWrapper {
-                        order: -1;
-                        width: fit-content;
-                      }
-                      .rdrStaticRanges {
-                        flex-direction: row;
-                        margin-right: 2px;
-                      }
-
-                      /* Sembunyikan bagian input manual */
-                      .rdrInputRanges {
-                        display: none !important;
-                      }
-
-                      .rdrStaticRangeLabel {
-                        padding: 10px 10px;
-                      }
-                      .rdrMonth {
-                        width: -moz-available;
-                      }
-                    `}</style>
-                    <div className='flex flex-row justify-end gap-3 mt-2'>
-                      <button
-                        className='px-4 py-1 bg-gray-500 text-white rounded'
-                        onClick={() => setIsOpenCalender(false)}
-                      >
-                        Done
-                      </button>
-                      <button
-                        className='px-4 py-1 bg-red-500 text-white rounded'
-                        onClick={handleReset}
-                      >
-                        Reset
-                      </button>
-                    </div>
-                  </div>
-                )}
-                </div>
                 <div className='flex flex-row gap-4 items-center justify-center'>
                   <p>
                     Menampilkan {startItem}-
@@ -1050,6 +1024,82 @@ const Transactions = ({ context = '' }) => {
                     <option value={15}>15</option>
                     <option value={20}>20</option>
                   </select>
+                  <div ref={calendarRef} className="relative inline-block">
+                    <button
+                      type='button'
+                      className='p-2 w-auto h-auto cursor-pointer border hover:bg-gray-100 rounded transition duration-150 ease-in-out flex items-center justify-center'
+                      onClick={() => setIsOpenCalender((prev) => !prev)}
+                    >
+                      <span className='text-nowrap px-1 truncate flex items-center gap-1'>
+                          {state[0]?.startDate ? (
+                            `${state[0].startDate.toLocaleDateString()} - ${state[0].endDate.toLocaleDateString()}`
+                          ) : (
+                            <Calendar size={16} className="text-gray-500" />
+                          )}
+                      </span>
+                    </button>
+                    {isOpenCalender && (
+                    <div className='absolute right-10 mt-2 bg-white p-4 rounded shadow-lg z-50'>
+                      {/* Tombol silang di sudut kanan atas */}
+                      <button
+                        onClick={() => setIsOpenCalender(false)}
+                        className='absolute top-2 right-2 text-gray-600 hover:text-black text-xl font-bold'
+                      >
+                        &times;
+                      </button>
+                      <DateRangePicker
+                        onChange={(item) => setState([item.selection])}
+                        showSelectionPreview={false}
+                        maxDate={new Date()}
+                        moveRangeOnFirstSelection={false}
+                        months={1}
+                        ranges={state}
+                        className='w-full'
+                      />
+                      <style>{`
+                        /* Atur container agar menjadi column */
+                        .rdrCalendarWrapper {
+                          display: flex;
+                          flex-direction: column;
+                        }
+                        .rdrDateRangePickerWrapper  {
+                          display: flex;
+                          flex-direction: column;
+                        }
+
+                        /* Pindahkan rdrStaticRanges ke atas */
+                        .rdrDefinedRangesWrapper {
+                          order: -1;
+                          width: fit-content;
+                        }
+                        .rdrStaticRanges {
+                          flex-direction: row;
+                          margin-right: 2px;
+                        }
+
+                        /* Sembunyikan bagian input manual */
+                        .rdrInputRanges {
+                          display: none !important;
+                        }
+
+                        .rdrStaticRangeLabel {
+                          padding: 10px 10px;
+                        }
+                        .rdrMonth {
+                          width: -moz-available;
+                        }
+                      `}</style>
+                      <div className='flex flex-row justify-end gap-3 mt-2'>
+                        <button
+                          className='px-4 py-1 bg-red-500 text-white rounded'
+                          onClick={handleReset}
+                        >
+                          Reset
+                        </button>
+                      </div>
+                    </div>
+                    )}
+                  </div>
                 </div>
               </div>
             </div>
@@ -1140,7 +1190,7 @@ const Transactions = ({ context = '' }) => {
                                     {saleOrder.products?.length > 1 && (
                                       <div className='flex flex-row gap-1 justify-start items-center'>
                                         {saleOrder.products
-                                          .slice(1, 6)
+                                          .slice(1, 4)
                                           .map((product, index) => (
                                             <Image
                                               key={index} // Tambahkan key untuk setiap elemen dalam map()
@@ -1149,16 +1199,21 @@ const Transactions = ({ context = '' }) => {
                                               className='object-contain object-center border border-gray_r-6 h-16 w-16 rounded-md'
                                             />
                                           ))}
-                                        <Link
-                                          href={`${router.pathname}/${saleOrder?.id}`}
-                                          className='text-sm text-red-500 text-nowrap'
-                                        >
-                                          {saleOrder.products?.length > 6
-                                            ? 'Lihat ' +
-                                              (saleOrder.products?.length - 6) +
-                                              ' produk lainnya'
-                                            : 'Lihat semua produk'}
-                                        </Link>
+                                        {saleOrder.products.length > 4 ? (
+                                          <Link
+                                            href={`${router.pathname}/${saleOrder?.id}`}
+                                            className='text-red-500 text-nowrap'
+                                          >
+                                            +{saleOrder.products.length - 4} lihat semua produk
+                                          </Link>
+                                        ) : (
+                                          <Link
+                                            href={`${router.pathname}/${saleOrder?.id}`}
+                                            className='text-red-500 text-nowrap'
+                                          >
+                                            Lihat semua produk
+                                          </Link>
+                                        )}
                                       </div>
                                     )}
                                   </div>
-- 
cgit v1.2.3

