260 lines
9.7 KiB
TypeScript
260 lines
9.7 KiB
TypeScript
import React from 'react';
|
||
import ImageField from '../ImageField';
|
||
import ListActionsPopover from '../ListActionsPopover';
|
||
import { useAppSelector } from '../../stores/hooks';
|
||
import dataFormatter from '../../helpers/dataFormatter';
|
||
import { Pagination } from '../Pagination';
|
||
import {saveFile} from "../../helpers/fileSaver";
|
||
import LoadingSpinner from "../LoadingSpinner";
|
||
import Link from 'next/link';
|
||
import {
|
||
formatSalesInvoicePaymentMethod,
|
||
formatSalesInvoiceStatus,
|
||
} from '../../helpers/salesInvoiceLabels';
|
||
|
||
import {hasPermission} from "../../helpers/userPermissions";
|
||
|
||
|
||
type Props = {
|
||
sales_invoices: any[];
|
||
loading: boolean;
|
||
onDelete: (id: string) => void;
|
||
currentPage: number;
|
||
numPages: number;
|
||
onPageChange: (page: number) => void;
|
||
};
|
||
|
||
const CardSales_invoices = ({
|
||
sales_invoices,
|
||
loading,
|
||
onDelete,
|
||
currentPage,
|
||
numPages,
|
||
onPageChange,
|
||
}: Props) => {
|
||
const asideScrollbarsStyle = useAppSelector(
|
||
(state) => state.style.asideScrollbarsStyle,
|
||
);
|
||
const bgColor = useAppSelector((state) => state.style.cardsColor);
|
||
const darkMode = useAppSelector((state) => state.style.darkMode);
|
||
const corners = useAppSelector((state) => state.style.corners);
|
||
const focusRing = useAppSelector((state) => state.style.focusRingColor);
|
||
|
||
const currentUser = useAppSelector((state) => state.auth.currentUser);
|
||
const hasUpdatePermission = hasPermission(currentUser, 'UPDATE_SALES_INVOICES')
|
||
|
||
|
||
return (
|
||
<div className={'p-4'}>
|
||
{loading && <LoadingSpinner />}
|
||
<ul
|
||
role='list'
|
||
className='grid grid-cols-1 gap-x-6 gap-y-8 lg:grid-cols-3 2xl:grid-cols-4 xl:gap-x-8'
|
||
>
|
||
{!loading && sales_invoices.map((item, index) => (
|
||
<li
|
||
key={item.id}
|
||
className={`overflow-hidden ${corners !== 'rounded-full'? corners : 'rounded-3xl'} border ${focusRing} border-gray-200 dark:border-dark-700 ${
|
||
darkMode ? 'aside-scrollbars-[slate]' : asideScrollbarsStyle
|
||
}`}
|
||
>
|
||
|
||
<div className={`flex items-center ${bgColor} p-6 gap-x-4 border-b border-gray-900/5 bg-gray-50 dark:bg-dark-800 relative`}>
|
||
|
||
<Link href={`/sales_invoices/sales_invoices-view/?id=${item.id}`} className='text-lg font-bold leading-6 line-clamp-1'>
|
||
{item.invoice_number}
|
||
</Link>
|
||
|
||
|
||
<div className='ml-auto '>
|
||
<ListActionsPopover
|
||
onDelete={onDelete}
|
||
itemId={item.id}
|
||
pathEdit={`/sales_invoices/sales_invoices-edit/?id=${item.id}`}
|
||
pathView={`/sales_invoices/sales_invoices-view/?id=${item.id}`}
|
||
|
||
hasUpdatePermission={hasUpdatePermission}
|
||
|
||
/>
|
||
</div>
|
||
</div>
|
||
<dl className='divide-y divide-stone-300 dark:divide-dark-700 px-6 py-4 text-sm leading-6 h-64 overflow-y-auto'>
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>المتجر</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ dataFormatter.shopsOneListFormatter(item.shop) }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>الكاشير</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ dataFormatter.usersOneListFormatter(item.cashier) }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>رقم الفاتورة</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ item.invoice_number }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>تاريخ ووقت البيع</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ dataFormatter.dateTimeFormatter(item.sold_at) }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>الحالة</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ formatSalesInvoiceStatus(item.status) }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>الإجمالي قبل الخصم</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ item.subtotal_amount }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>الخصم</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ item.discount_amount }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>الإجمالي النهائي</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ item.total_amount }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>إجمالي التكلفة</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ item.total_cost_amount }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>إجمالي الربح</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ item.total_profit_amount }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>طريقة الدفع</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ formatSalesInvoicePaymentMethod(item.payment_method) }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>ملاحظات</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ item.notes }
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div className='flex justify-between gap-x-4 py-3'>
|
||
<dt className=' text-gray-500 dark:text-dark-600'>بنود الفاتورة</dt>
|
||
<dd className='flex items-start gap-x-2'>
|
||
<div className='font-medium line-clamp-4'>
|
||
{ dataFormatter.sales_invoice_itemsManyListFormatter(item.items).join(', ')}
|
||
</div>
|
||
</dd>
|
||
</div>
|
||
|
||
|
||
|
||
</dl>
|
||
</li>
|
||
))}
|
||
{!loading && sales_invoices.length === 0 && (
|
||
<div className='col-span-full flex items-center justify-center h-40'>
|
||
<p className=''>لا توجد بيانات للعرض</p>
|
||
</div>
|
||
)}
|
||
</ul>
|
||
<div className={'flex items-center justify-center my-6'}>
|
||
<Pagination
|
||
currentPage={currentPage}
|
||
numPages={numPages}
|
||
setCurrentPage={onPageChange}
|
||
/>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default CardSales_invoices;
|