diff --git a/package-lock.json b/package-lock.json
index 40d0887..ad52b11 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
"@fortawesome/free-brands-svg-icons": "^5.15.4",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/react-fontawesome": "^0.1.16",
+ "@heroicons/react": "^1.0.5",
"@reduxjs/toolkit": "^1.7.1",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
@@ -2148,6 +2149,14 @@
"react": ">=16.x"
}
},
+ "node_modules/@heroicons/react": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-1.0.5.tgz",
+ "integrity": "sha512-UDMyLM2KavIu2vlWfMspapw9yii7aoLwzI2Hudx4fyoPwfKfxU8r3cL8dEBXOjcLG0/oOONZzbT14M1HoNtEcg==",
+ "peerDependencies": {
+ "react": ">= 16"
+ }
+ },
"node_modules/@humanwhocodes/config-array": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz",
@@ -18327,6 +18336,12 @@
"prop-types": "^15.7.2"
}
},
+ "@heroicons/react": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-1.0.5.tgz",
+ "integrity": "sha512-UDMyLM2KavIu2vlWfMspapw9yii7aoLwzI2Hudx4fyoPwfKfxU8r3cL8dEBXOjcLG0/oOONZzbT14M1HoNtEcg==",
+ "requires": {}
+ },
"@humanwhocodes/config-array": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz",
diff --git a/package.json b/package.json
index f7feb74..a2057b3 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"@fortawesome/free-brands-svg-icons": "^5.15.4",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/react-fontawesome": "^0.1.16",
+ "@heroicons/react": "^1.0.5",
"@reduxjs/toolkit": "^1.7.1",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
diff --git a/src/App.js b/src/App.js
index c8a3bb9..1c0238e 100644
--- a/src/App.js
+++ b/src/App.js
@@ -43,6 +43,8 @@ import SpecifiedDomainRadarChart from "./components/Chart/SpecifiedDomainRadarCh
import Design1 from "./components/ProductSalesAmount/Design1";
import Design2 from "./components/ProductSalesAmount/Design2";
import TableDesign1 from "./components/Table/Design1";
+import ReactTable from "./components/ReactTable";
+import ReactTable2 from "./components/ReactTable2";
function App() {
return (
@@ -86,6 +88,8 @@ function App() {
{/* */}
{/* */}
{/* */}
+ {/* */}
+
);
diff --git a/src/components/ReactTable/Table.js b/src/components/ReactTable/Table.js
new file mode 100644
index 0000000..0ddba7e
--- /dev/null
+++ b/src/components/ReactTable/Table.js
@@ -0,0 +1,294 @@
+import React from "react";
+
+import {
+ useTable,
+ useGlobalFilter,
+ useAsyncDebounce,
+ useSortBy,
+ usePagination,
+} from "react-table"; // new
+
+import {
+ ChevronDoubleLeftIcon,
+ ChevronLeftIcon,
+ ChevronRightIcon,
+ ChevronDoubleRightIcon,
+} from "@heroicons/react/solid";
+
+import { Button, PageButton } from "./shared/Button";
+import { classNames } from "./shared/Utils";
+import { SortIcon, SortUpIcon, SortDownIcon } from "./shared/Icons";
+
+function GlobalFilter({
+ preGlobalFilteredRows,
+ globalFilter,
+ setGlobalFilter,
+}) {
+ const count = preGlobalFilteredRows.length;
+ const [value, setValue] = React.useState(globalFilter);
+ const onChange = useAsyncDebounce((value) => {
+ setGlobalFilter(value || undefined);
+ }, 200);
+
+ return (
+
+ Search:{" "}
+ {
+ setValue(e.target.value);
+ onChange(e.target.value);
+ }}
+ placeholder={`${count} records...`}
+ />
+
+ );
+}
+
+// This is a custom filter UI for selecting
+export function StatusPill({ value }) {
+ // const status = value ? value.toLowerCase() : "unknown";
+
+ return (
+ //
+ // {/* {status} */}
+ // {status ? "فعال" : "غیر فعال"}
+ //
+
+ {value ? "فعال" : "غیر فعال"}
+
+ );
+ console.log(value);
+}
+
+function Table({ columns, data }) {
+ // Use the state and functions returned from useTable to build your UI
+ const {
+ getTableProps,
+ getTableBodyProps,
+ headerGroups,
+ rows,
+ prepareRow,
+ //new
+ page, // Instead of using 'rows', we'll use page,
+ // which has only the rows for the active page
+
+ // The rest of these things are super handy, too ;)
+ canPreviousPage,
+ canNextPage,
+ pageOptions,
+ pageCount,
+ gotoPage,
+ nextPage,
+ previousPage,
+ setPageSize,
+
+ state, // new
+ preGlobalFilteredRows, // new
+ setGlobalFilter,
+ } = useTable(
+ {
+ columns,
+ data,
+ },
+ useGlobalFilter,
+ useSortBy, // new
+ usePagination
+ );
+
+ // Render the UI for your table
+ return (
+ <>
+
+
+ {headerGroups.map((headerGroup) =>
+ headerGroup.headers.map((column) =>
+ column.Filter ? (
+
+ {column.render("Filter")}
+
+ ) : null
+ )
+ )}
+
+ {/* table */}
+
+
+
+
+
+
+ {headerGroups.map((headerGroup) => (
+
+ {headerGroup.headers.map((column) => (
+ // Add the sorting props to control sorting. For this example
+ // we can add them into the header props
+
+
+ {column.render("Header")}
+ {/* Add a sort direction indicator */}
+
+ {column.isSorted ? (
+ column.isSortedDesc ? (
+
+ ) : (
+
+ )
+ ) : (
+
+ )}
+
+
+
+ ))}
+
+ ))}
+
+
+ {page.map((row, i) => {
+ // new
+ prepareRow(row);
+ return (
+
+ {row.cells.map((cell) => {
+ return (
+
+ {cell.column.Cell.name === "defaultRenderer" ? (
+
+ {cell.render("Cell")}
+
+ ) : (
+ cell.render("Cell")
+ )}
+
+ );
+ })}
+
+ );
+ })}
+
+
+
+
+
+
+ {/* Pagination */}
+
+
+ previousPage()} disabled={!canPreviousPage}>
+ Previous
+
+ nextPage()} disabled={!canNextPage}>
+ Next
+
+
+
+ {/* pagintaion */}
+
+
+ صفحه {state.pageIndex + 1} از{" "}
+ {pageOptions.length}
+
+
+ ایتم های صفحه
+ {
+ setPageSize(Number(e.target.value));
+ }}
+ >
+ {[5, 10, 20].map((pageSize) => (
+
+ نمایش {pageSize}
+
+ ))}
+
+
+
+ {/* arrows */}
+
+
+ gotoPage(pageCount - 1)}
+ disabled={!canNextPage}
+ >
+ Last
+
+
+ nextPage()} disabled={!canNextPage}>
+ Next
+
+
+
+ previousPage()}
+ disabled={!canPreviousPage}
+ >
+ Previous
+
+
+ gotoPage(0)}
+ disabled={!canPreviousPage}
+ >
+ First
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Table;
diff --git a/src/components/ReactTable/index.js b/src/components/ReactTable/index.js
new file mode 100644
index 0000000..4573be4
--- /dev/null
+++ b/src/components/ReactTable/index.js
@@ -0,0 +1,58 @@
+import React from "react";
+import Table, { AvatarCell, SelectColumnFilter, StatusPill } from "./Table"; // new
+
+const getData = () => {
+ const data = [
+ {
+ name: "مایکروویر سامسونگ مدل ",
+ status: true,
+ date: "1400 / 09 / 21",
+ price: 20000,
+ },
+ {
+ name: "مایکروویر سامسونگ مدل ",
+ status: false,
+ date: "1400 / 09 / 21",
+ price: 20000,
+ },
+ ];
+ return [...data, ...data, ...data];
+};
+
+function ReactTable() {
+ const columns = React.useMemo(
+ () => [
+ {
+ Header: "عنوان",
+ accessor: "name",
+ },
+ {
+ Header: "وضعیت",
+ accessor: "status",
+ },
+ {
+ Header: "تاریخ",
+ accessor: "date",
+ },
+ {
+ Header: "مبلغ پرداختی",
+ accessor: "price",
+ },
+ ],
+ []
+ );
+
+ const data = React.useMemo(() => getData(), []);
+
+ return (
+
+ );
+}
+
+export default ReactTable;
diff --git a/src/components/ReactTable/shared/Button.js b/src/components/ReactTable/shared/Button.js
new file mode 100644
index 0000000..0eb5e88
--- /dev/null
+++ b/src/components/ReactTable/shared/Button.js
@@ -0,0 +1,35 @@
+import React from 'react'
+import { classNames } from './Utils'
+
+export function Button({ children, className, ...rest }) {
+ return (
+
+ {children}
+
+ )
+}
+
+export function PageButton({ children, className, ...rest }) {
+ return (
+
+ {children}
+
+ )
+}
+
diff --git a/src/components/ReactTable/shared/Icons.js b/src/components/ReactTable/shared/Icons.js
new file mode 100644
index 0000000..8751e5e
--- /dev/null
+++ b/src/components/ReactTable/shared/Icons.js
@@ -0,0 +1,17 @@
+export function SortIcon({ className }) {
+ return (
+
+ )
+}
+
+export function SortUpIcon({ className }) {
+ return (
+
+ )
+}
+
+export function SortDownIcon({ className }) {
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/ReactTable/shared/Utils.js b/src/components/ReactTable/shared/Utils.js
new file mode 100644
index 0000000..91dcb3e
--- /dev/null
+++ b/src/components/ReactTable/shared/Utils.js
@@ -0,0 +1,3 @@
+export function classNames(...classes) {
+ return classes.filter(Boolean).join(" ");
+}
\ No newline at end of file
diff --git a/src/components/ReactTable2/Table.js b/src/components/ReactTable2/Table.js
new file mode 100644
index 0000000..844d37e
--- /dev/null
+++ b/src/components/ReactTable2/Table.js
@@ -0,0 +1,305 @@
+import React from "react";
+import {
+ useTable,
+ useFilters,
+ useGlobalFilter,
+ useAsyncDebounce,
+ useSortBy,
+ usePagination,
+} from "react-table";
+import {
+ ChevronDoubleLeftIcon,
+ ChevronLeftIcon,
+ ChevronRightIcon,
+ ChevronDoubleRightIcon,
+} from "@heroicons/react/solid";
+import { Button, PageButton } from "./shared/Button";
+import { classNames } from "./shared/Utils";
+import { SortIcon, SortUpIcon, SortDownIcon } from "./shared/Icons";
+
+// Define a default UI for filtering
+function GlobalFilter({
+ preGlobalFilteredRows,
+ globalFilter,
+ setGlobalFilter,
+}) {
+ const count = preGlobalFilteredRows.length;
+ const [value, setValue] = React.useState(globalFilter);
+ const onChange = useAsyncDebounce((value) => {
+ setGlobalFilter(value || undefined);
+ }, 200);
+
+ return (
+
+ Search:
+ {
+ setValue(e.target.value);
+ onChange(e.target.value);
+ }}
+ placeholder={`${count} records...`}
+ />
+
+ );
+}
+
+export function StatusPill({ value }) {
+ // const status = value ? value.toLowerCase() : "unknown";
+
+ return (
+
+ {value ? "فعال" : "غیر فعال"}
+
+ );
+}
+
+// export function AvatarCell({ value, column, row }) {
+// return (
+//
+// {/* برای عکس */}
+// {/*
+//
+//
*/}
+// {/* اگر بخواهیم در کنار عنوان یک محتوا دیگه ای بنویسیم */}
+// {/*
+//
{value}
+//
+// {row.original[column.emailAccessor]}
+//
+//
*/}
+//
+// );
+// }
+
+function Table({ columns, data }) {
+ // Use the state and functions returned from useTable to build your UI
+ const {
+ getTableProps,
+ getTableBodyProps,
+ headerGroups,
+ prepareRow,
+ page, // Instead of using 'rows', we'll use page,
+ // which has only the rows for the active page
+
+ // The rest of these things are super handy, too ;)
+ canPreviousPage,
+ canNextPage,
+ pageOptions,
+ pageCount,
+ gotoPage,
+ nextPage,
+ previousPage,
+ setPageSize,
+
+ state,
+ preGlobalFilteredRows,
+ setGlobalFilter,
+ } = useTable(
+ {
+ columns,
+ data,
+ },
+ useFilters, // useFilters!
+ useGlobalFilter,
+ useSortBy,
+ usePagination // new
+ );
+
+ // Render the UI for your table
+ return (
+ <>
+
+
+ {headerGroups.map((headerGroup) =>
+ headerGroup.headers.map((column) =>
+ column.Filter ? (
+
+ {column.render("Filter")}
+
+ ) : null
+ )
+ )}
+
+ {/* table */}
+
+
+
+
+
+
+ {headerGroups.map((headerGroup) => (
+
+ {headerGroup.headers.map((column) => (
+ // Add the sorting props to control sorting. For this example
+ // we can add them into the header props
+
+
+ {column.render("Header")}
+ {/* Add a sort direction indicator */}
+
+ {column.isSorted ? (
+ column.isSortedDesc ? (
+
+ ) : (
+
+ )
+ ) : (
+
+ )}
+
+
+
+ ))}
+
+ ))}
+
+
+ {page.map((row, i) => {
+ // new
+ prepareRow(row);
+ return (
+
+ {row.cells.map((cell) => {
+ return (
+
+ {cell.column.Cell.name === "defaultRenderer" ? (
+
+ {cell.render("Cell")}
+
+ ) : (
+ cell.render("Cell")
+ )}
+
+ );
+ })}
+
+ );
+ })}
+
+
+
+
+
+
+ {/* Pagination */}
+
+
+ previousPage()} disabled={!canPreviousPage}>
+ Previous
+
+ nextPage()} disabled={!canNextPage}>
+ Next
+
+
+
+ {/* numbers */}
+
+
+ صفحه {state.pageIndex + 1} از
+ {pageOptions.length}
+
+
+ ایتم های موجود در هر صفحه
+ {
+ setPageSize(Number(e.target.value));
+ }}
+ >
+ {[5, 10, 20].map((pageSize) => (
+
+ نمایش {pageSize}
+
+ ))}
+
+
+
+ {/* arrows */}
+
+
+ gotoPage(0)}
+ disabled={!canPreviousPage}
+ >
+ First
+
+
+
+ previousPage()}
+ disabled={!canPreviousPage}
+ >
+ Previous
+
+
+
+ nextPage()} disabled={!canNextPage}>
+ Next
+
+
+
+ gotoPage(pageCount - 1)}
+ disabled={!canNextPage}
+ >
+ Last
+
+
+
+
+
+
+ >
+ );
+}
+
+export default Table;
diff --git a/src/components/ReactTable2/index.js b/src/components/ReactTable2/index.js
new file mode 100644
index 0000000..657057f
--- /dev/null
+++ b/src/components/ReactTable2/index.js
@@ -0,0 +1,90 @@
+import React from "react";
+import Table, { AvatarCell, SelectColumnFilter, StatusPill } from "./Table"; // new
+
+const getData = () => {
+ const data = [
+ {
+ name: "مایکروویر سامسونگ مدل ",
+ // email: "jane.cooper@example.com",
+ status: true,
+ date: "1400/09/21",
+ price: 20000,
+ // imgUrl:
+ // "https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=4&w=256&h=256&q=60",
+ },
+ {
+ name: "آزمون آنلاین درس علوم تجربی ",
+ status: false,
+ date: "1400/09/21",
+ price: 18000,
+ },
+ {
+ name: "مایکروویر سامسونگ مدل ",
+ status: true,
+ date: "1400/09/21",
+ price: 20000,
+ },
+ {
+ name: "آزمون آنلاین درس علوم تجربی ",
+ status: false,
+ date: "1400/09/21",
+ price: 18000,
+ },
+ {
+ name: "مایکروویر سامسونگ مدل ",
+ status: true,
+ date: "1400/09/21",
+ price: 27000000,
+ },
+ {
+ name: "آزمون آنلاین درس علوم تجربی ",
+ status: false,
+ date: "1400/09/21",
+ price: 1000,
+ },
+ ];
+ return [...data, ...data, ...data];
+};
+
+const ReactTable2 = () => {
+ const columns = React.useMemo(
+ () => [
+ {
+ Header: "عنوان",
+ accessor: "name",
+ // اگر بخواهیم عکسی در جدول نشان بدیم یا یک محتوایی در کنار عنوان داشته باشیم اول باید اواتار سل رو در فایل تیبل جی اس ان کامنت کنیم و بعد ...
+ // Cell: AvatarCell,
+ // imgAccessor: "imgUrl",
+ // emailAccessor: "email",
+ },
+ {
+ Header: "وضعیت",
+ accessor: "status",
+ Cell: StatusPill,
+ },
+ {
+ Header: "تاریخ",
+ accessor: "date",
+ },
+ {
+ Header: "مبلغ پرداختی",
+ accessor: "price",
+ },
+ ],
+ []
+ );
+
+ const data = React.useMemo(() => getData(), []);
+
+ return (
+
+ );
+};
+
+export default ReactTable2;
diff --git a/src/components/ReactTable2/shared/Button.js b/src/components/ReactTable2/shared/Button.js
new file mode 100644
index 0000000..0eb5e88
--- /dev/null
+++ b/src/components/ReactTable2/shared/Button.js
@@ -0,0 +1,35 @@
+import React from 'react'
+import { classNames } from './Utils'
+
+export function Button({ children, className, ...rest }) {
+ return (
+
+ {children}
+
+ )
+}
+
+export function PageButton({ children, className, ...rest }) {
+ return (
+
+ {children}
+
+ )
+}
+
diff --git a/src/components/ReactTable2/shared/Icons.js b/src/components/ReactTable2/shared/Icons.js
new file mode 100644
index 0000000..8751e5e
--- /dev/null
+++ b/src/components/ReactTable2/shared/Icons.js
@@ -0,0 +1,17 @@
+export function SortIcon({ className }) {
+ return (
+
+ )
+}
+
+export function SortUpIcon({ className }) {
+ return (
+
+ )
+}
+
+export function SortDownIcon({ className }) {
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/ReactTable2/shared/Utils.js b/src/components/ReactTable2/shared/Utils.js
new file mode 100644
index 0000000..91dcb3e
--- /dev/null
+++ b/src/components/ReactTable2/shared/Utils.js
@@ -0,0 +1,3 @@
+export function classNames(...classes) {
+ return classes.filter(Boolean).join(" ");
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 310739e..b7237fc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1258,6 +1258,11 @@
dependencies:
"prop-types" "^15.7.2"
+"@heroicons/react@^1.0.5":
+ "integrity" "sha512-UDMyLM2KavIu2vlWfMspapw9yii7aoLwzI2Hudx4fyoPwfKfxU8r3cL8dEBXOjcLG0/oOONZzbT14M1HoNtEcg=="
+ "resolved" "https://registry.npmjs.org/@heroicons/react/-/react-1.0.5.tgz"
+ "version" "1.0.5"
+
"@humanwhocodes/config-array@^0.9.2":
"integrity" "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA=="
"resolved" "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz"