├── src ├── vite-env.d.ts ├── Components │ ├── Form │ │ ├── FilterProduct │ │ │ ├── Types.ts │ │ │ └── index.tsx │ │ ├── CreateProduct │ │ │ ├── Types.ts │ │ │ └── index.tsx │ │ ├── UpdateProduct │ │ │ ├── Types.ts │ │ │ └── index.tsx │ │ ├── FormikControl │ │ │ ├── index.tsx │ │ │ ├── textArea.tsx │ │ │ ├── input.tsx │ │ │ └── select.tsx │ │ └── DeleteProduct │ │ │ └── index.tsx │ ├── Header │ │ ├── index.tsx │ │ └── NavLinks.tsx │ ├── Product │ │ ├── ProductTable │ │ │ ├── Rows.tsx │ │ │ ├── Cells.tsx │ │ │ └── index.tsx │ │ ├── index.tsx │ │ └── Pagination │ │ │ └── index.tsx │ ├── Ui │ │ ├── Error.tsx │ │ └── Spinner.tsx │ └── Modal │ │ └── index.tsx ├── Pages │ ├── About │ │ └── index.tsx │ ├── Layout │ │ └── index.tsx │ └── Home │ │ └── index.tsx ├── StateManagment │ ├── Base │ │ └── index.tsx │ ├── Client │ │ └── index.tsx │ └── Service │ │ └── Product.tsx ├── index.css ├── main.tsx ├── Model │ └── Product.ts ├── Utils │ └── Toast.tsx ├── Hook │ ├── useDeleteProduct │ │ └── index.tsx │ ├── useCreateProduct │ │ └── index.tsx │ ├── useUpdateProduct │ │ └── index.tsx │ └── useGetProduct │ │ └── index.tsx ├── App.tsx └── assets │ └── react.svg ├── .Prettierrc ├── public ├── 1.jpg └── vite.svg ├── postcss.config.js ├── vite.config.ts ├── Readme.md ├── tailwind.config.js ├── tsconfig.node.json ├── .gitignore ├── .eslintrc.cjs ├── index.html ├── tsconfig.json ├── package.json └── db.json /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /.Prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /public/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alireza-WebDeveloper/ReactQuery-Dashboard/HEAD/public/1.jpg -------------------------------------------------------------------------------- /src/Components/Form/FilterProduct/Types.ts: -------------------------------------------------------------------------------- 1 | export type initialValuesState = { 2 | price: string; 3 | }; 4 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /src/Pages/About/index.tsx: -------------------------------------------------------------------------------- 1 | const AboutPage = () => { 2 | return <>about page; 3 | }; 4 | 5 | export default AboutPage; 6 | -------------------------------------------------------------------------------- /src/StateManagment/Base/index.tsx: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const BaseApi = axios.create({ 4 | baseURL: 'http://localhost:5007', 5 | }); 6 | 7 | export default BaseApi; 8 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer base { 6 | a { 7 | text-decoration: none; 8 | color: inherit; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react-swc' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import ReactDOM from 'react-dom/client'; 2 | import App from './App.tsx'; 3 | import './index.css'; 4 | 5 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 6 | 7 | ); 8 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # How to install the program 2 | # 1 : npm install 3 | # 2 : npm run db 4 | # 3 : npm run dev 5 | 6 | 7 | 8 | # 1.Note : You Can CRUD With Pagination Data Table 9 | # 2.Note : Cache Data When Change Route 10 | 11 | -------------------------------------------------------------------------------- /src/Model/Product.ts: -------------------------------------------------------------------------------- 1 | export interface ProductState { 2 | id: number; 3 | name: string; 4 | description: string; 5 | year_of_creation: number; 6 | rating: number; 7 | views: number; 8 | country: string; 9 | price: number; 10 | } 11 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | darkMode: 'class', 4 | content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], 5 | theme: { 6 | extend: {}, 7 | }, 8 | plugins: [], 9 | }; 10 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /src/StateManagment/Client/index.tsx: -------------------------------------------------------------------------------- 1 | import { QueryClient } from '@tanstack/react-query'; 2 | const queryClientStore = new QueryClient({ 3 | defaultOptions: { 4 | // 5 * 1000 5 | queries: { 6 | staleTime: 0, 7 | }, 8 | }, 9 | }); 10 | 11 | export default queryClientStore; 12 | -------------------------------------------------------------------------------- /src/Components/Form/CreateProduct/Types.ts: -------------------------------------------------------------------------------- 1 | // Types 2 | export type initialValuesState = { 3 | name: string; 4 | description: string; 5 | year_of_creation: number; 6 | rating: number; 7 | views: number; 8 | country: string; 9 | price: number; 10 | }; 11 | export interface CreateProductProps { 12 | onClose(): void; 13 | } 14 | -------------------------------------------------------------------------------- /src/Pages/Layout/index.tsx: -------------------------------------------------------------------------------- 1 | import { Outlet } from 'react-router-dom'; 2 | import Header from '../../Components/Header'; 3 | 4 | const Layout = () => { 5 | return ( 6 | <> 7 |
8 |
{}
9 | 10 | ); 11 | }; 12 | 13 | export default Layout; 14 | -------------------------------------------------------------------------------- /src/Utils/Toast.tsx: -------------------------------------------------------------------------------- 1 | import { ToastContainerProps } from 'react-toastify'; 2 | // Types 3 | const toastOptions: ToastContainerProps = { 4 | position: 'top-center', 5 | autoClose: 2000, 6 | hideProgressBar: false, 7 | closeOnClick: true, 8 | pauseOnHover: true, 9 | draggable: true, 10 | theme: 'dark', 11 | }; 12 | 13 | export { toastOptions }; 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { browser: true, es2020: true }, 3 | extends: [ 4 | 'eslint:recommended', 5 | 'plugin:@typescript-eslint/recommended', 6 | 'plugin:react-hooks/recommended', 7 | ], 8 | parser: '@typescript-eslint/parser', 9 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 10 | plugins: ['react-refresh'], 11 | rules: { 12 | 'react-refresh/only-export-components': 'warn', 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /src/Components/Form/UpdateProduct/Types.ts: -------------------------------------------------------------------------------- 1 | import { ProductState } from '../../../Model/Product'; 2 | 3 | // Types 4 | export type initialValuesState = { 5 | name: string; 6 | description: string; 7 | year_of_creation: number; 8 | rating: number; 9 | views: number; 10 | country: string; 11 | price: number; 12 | }; 13 | export interface UpdateProductProps { 14 | statusDelete: any; 15 | onClose(): void; 16 | selectProduct: ProductState; 17 | } 18 | -------------------------------------------------------------------------------- /src/Components/Header/index.tsx: -------------------------------------------------------------------------------- 1 | import NavLinks from './NavLinks'; 2 | 3 | const Header = () => { 4 | return ( 5 |
6 |
7 | 13 |
14 |
15 | ); 16 | }; 17 | 18 | export default Header; 19 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /src/Components/Header/NavLinks.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | interface NavLinksProps { 5 | routs: { id: number; text: string; to: string }[]; 6 | } 7 | 8 | const NavLinks: React.FC = ({ routs }) => { 9 | const createLink = () => { 10 | return routs.map((route) => { 11 | return ( 12 | 17 | {route.text} 18 | 19 | ); 20 | }); 21 | }; 22 | return
{createLink()}
; 23 | }; 24 | 25 | export default NavLinks; 26 | -------------------------------------------------------------------------------- /src/Components/Product/ProductTable/Rows.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ProductState } from '../../../Model/Product'; 3 | 4 | interface RowsState { 5 | products: ProductState[]; 6 | } 7 | const Rows: React.FC = ({ products }) => { 8 | return ( 9 | 10 | 11 | {products && 12 | Object.keys(products[0]) 13 | .concat('options') 14 | .map((title, index) => { 15 | return ( 16 | 17 | {title} 18 | 19 | ); 20 | })} 21 | 22 | 23 | ); 24 | }; 25 | 26 | export default Rows; 27 | -------------------------------------------------------------------------------- /src/Pages/Home/index.tsx: -------------------------------------------------------------------------------- 1 | import Product from '../../Components/Product'; 2 | import Error from '../../Components/Ui/Error'; 3 | import Spinner from '../../Components/Ui/Spinner'; 4 | import useGetProduct from '../../Hook/useGetProduct'; 5 | 6 | const HomePage = () => { 7 | const { data, status } = useGetProduct(); 8 | 9 | if (status === 'loading') return ; 10 | if (status === 'error') return ; 11 | 12 | return ( 13 |
14 | {data && data?.length >= 1 ? ( 15 | 16 | ) : ( 17 |

18 | There is no product available 19 |

20 | )} 21 |
22 | ); 23 | }; 24 | 25 | export default HomePage; 26 | -------------------------------------------------------------------------------- /src/Components/Form/FormikControl/index.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { FC } from 'react'; 3 | import Input from './input'; 4 | import TextArea from './textArea'; 5 | import Select from './select'; 6 | 7 | type FormikControlProps = { 8 | control: 'input' | 'range' | 'select' | 'textarea' | 'file'; 9 | name: string; 10 | type?: string; 11 | label?: string; 12 | options?: { key: string; value: string }[]; 13 | }; 14 | 15 | const FormikControl: FC = ({ control, ...otherProps }) => { 16 | switch (control) { 17 | case 'input': 18 | return ; 19 | case 'textarea': 20 | return