diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7532bd3..da43eea 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,15 @@ ### Contribution Guide -- Feel free to contribute to this repo by raising the __pull request__ -- Use the proper names for variable and functions +#### PR rules + +- Please raise the **pull request** if want to contribute by fixing bugs, + improving the code or adding the test cases +- If you want to enhance the project, please create an issue and can be + discussed before proceeding + +#### Codebase rules + - Do not import libraries unless needed - Test well before submitting the PR +- Code quality is the primary requirement +- Format the files before submission diff --git a/README.md b/README.md index 4968944..88bfb5b 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,9 @@ Features - [React](https://react.dev/) - [Redux Toolkit](https://redux-toolkit.js.org/) +- [React Router](https://reactrouter.com/en/main/) +- [React Switch](https://react-switch.netlify.app/) +- [Sonner](https://sonner.emilkowal.ski/) - [Sass](https://sass-lang.com/) - [Vite](https://vitejs.dev/) (Bundler) diff --git a/package-lock.json b/package-lock.json index fe23c45..4c1c7bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "algo-visualizer", "version": "0.0.0", + "license": "MIT", "dependencies": { "@reduxjs/toolkit": "^1.9.5", "react": "^18.2.0", @@ -14,7 +15,8 @@ "react-redux": "^8.1.2", "react-router-dom": "^6.16.0", "react-switch": "^7.0.0", - "redux-persist": "^6.0.0" + "redux-persist": "^6.0.0", + "sonner": "^1.0.3" }, "devDependencies": { "@testing-library/jest-dom": "^6.1.3", @@ -32,7 +34,7 @@ "eslint-plugin-react-refresh": "^0.3.5", "eslint-plugin-unused-imports": "^3.0.0", "jsdom": "^22.1.0", - "postcss": "^8.4.30", + "postcss": "^8.4.31", "sass": "^1.68.0", "stylelint": "^15.10.3", "stylelint-config-recess-order": "^4.3.0", @@ -42,6 +44,9 @@ "typescript": "^5.2.2", "vite": "^4.3.9", "vitest": "^0.34.5" + }, + "engines": { + "node": ">=18.18.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -4604,9 +4609,9 @@ } }, "node_modules/postcss": { - "version": "8.4.30", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz", - "integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "dev": true, "funding": [ { @@ -5414,6 +5419,15 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/sonner": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.0.3.tgz", + "integrity": "sha512-hBoA2zKuYW3lUnpx4K0vAn8j77YuYiwvP9sLQfieNS2pd5FkT20sMyPTDJnl9S+5T27ZJbwQRPiujwvDBwhZQg==", + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", diff --git a/package.json b/package.json index 79d5381..7903df4 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "react-redux": "^8.1.2", "react-router-dom": "^6.16.0", "react-switch": "^7.0.0", - "redux-persist": "^6.0.0" + "redux-persist": "^6.0.0", + "sonner": "^1.0.3" }, "devDependencies": { "@testing-library/jest-dom": "^6.1.3", @@ -40,7 +41,7 @@ "eslint-plugin-react-refresh": "^0.3.5", "eslint-plugin-unused-imports": "^3.0.0", "jsdom": "^22.1.0", - "postcss": "^8.4.30", + "postcss": "^8.4.31", "sass": "^1.68.0", "stylelint": "^15.10.3", "stylelint-config-recess-order": "^4.3.0", diff --git a/src/apps/sorting-visualizer/__tests__/hooks/use-algo.hook.spec.ts b/src/apps/sorting-visualizer/__tests__/hooks/use-algo.hook.spec.ts index 67b322e..ee128d7 100644 --- a/src/apps/sorting-visualizer/__tests__/hooks/use-algo.hook.spec.ts +++ b/src/apps/sorting-visualizer/__tests__/hooks/use-algo.hook.spec.ts @@ -6,7 +6,7 @@ import { import { renderHook, waitFor } from '@testing-library/react'; import { algoList } from '@/apps/sorting-visualizer/sorting-algorithms/algo-list'; -import { getRndmNumInRange } from '../../helpers/array-helpers'; +import { getRndmNumInRange } from '@/apps/sorting-visualizer/helpers/array-helpers'; import { initialArray } from '@/apps/sorting-visualizer/config'; import useAlgo from '@/apps/sorting-visualizer/hooks/use-algo.hook'; diff --git a/src/apps/sorting-visualizer/config.ts b/src/apps/sorting-visualizer/config.ts index 279d982..2aaa6c5 100644 --- a/src/apps/sorting-visualizer/config.ts +++ b/src/apps/sorting-visualizer/config.ts @@ -3,6 +3,7 @@ import { algoList } from './sorting-algorithms/algo-list'; export const menuItems = algoList.map((item) => item.name).concat('all'); export const initialArray = [6, 8, 3, 5, 1, 9, 2, 7, 4]; export const numberGenerator = { min: 10, max: 40 }; +export const sortCompletionMessage = 'Sorting is complete'; export const cellCSS = { size: 50, diff --git a/src/apps/sorting-visualizer/layouts/all-algorithm.layout.tsx b/src/apps/sorting-visualizer/layouts/all-algorithm.layout.tsx index 113a50c..8d5bc28 100644 --- a/src/apps/sorting-visualizer/layouts/all-algorithm.layout.tsx +++ b/src/apps/sorting-visualizer/layouts/all-algorithm.layout.tsx @@ -7,6 +7,8 @@ import Visualizer from '@/apps/sorting-visualizer/components/visualizer/visualiz import { algoList } from '@/apps/sorting-visualizer/sorting-algorithms/algo-list'; import classes from './layout.module.scss'; import { setIsPlaying } from '@/apps/sorting-visualizer/store/sorting-visualizer.slice'; +import { sortCompletionMessage } from '../config'; +import { toast } from 'sonner'; import useCompletion from '@/apps/sorting-visualizer/hooks/use-completion.hook'; import { useEffect } from 'react'; @@ -26,6 +28,7 @@ function AllAlgorithmLayout() { useEffect(() => { if (isComplete) { + toast.success(sortCompletionMessage); dispatch(setIsPlaying(null)); } }, [dispatch, isComplete]); diff --git a/src/apps/sorting-visualizer/layouts/main.layout.tsx b/src/apps/sorting-visualizer/layouts/main.layout.tsx index 0f698df..c000230 100644 --- a/src/apps/sorting-visualizer/layouts/main.layout.tsx +++ b/src/apps/sorting-visualizer/layouts/main.layout.tsx @@ -2,6 +2,7 @@ import Controller from '@/apps/sorting-visualizer/components/controller/controll import ModeIcon from '@/apps/sorting-visualizer/components/theme/mode-icon'; import Navbar from '@/apps/sorting-visualizer/components/navbar/navbar'; import { PropsWithChildren } from 'react'; +import { Toaster } from 'sonner'; import classes from './layout.module.scss'; import { menuItems } from '@/apps/sorting-visualizer/config'; @@ -12,6 +13,7 @@ function MainLayout({ children }: PropsWithChildren) {
{children}
+ ); } diff --git a/src/apps/sorting-visualizer/layouts/single-algorithm.layout.tsx b/src/apps/sorting-visualizer/layouts/single-algorithm.layout.tsx index 12736e6..8886760 100644 --- a/src/apps/sorting-visualizer/layouts/single-algorithm.layout.tsx +++ b/src/apps/sorting-visualizer/layouts/single-algorithm.layout.tsx @@ -5,6 +5,8 @@ import NoInput from '@/apps/sorting-visualizer/components/visualizer/no-input'; import Visualizer from '@/apps/sorting-visualizer/components/visualizer/visualizer'; import { algoList } from '@/apps/sorting-visualizer/sorting-algorithms/algo-list'; import { setIsPlaying } from '@/apps/sorting-visualizer/store/sorting-visualizer.slice'; +import { sortCompletionMessage } from '../config'; +import { toast } from 'sonner'; import useCompletion from '@/apps/sorting-visualizer/hooks/use-completion.hook'; import { useEffect } from 'react'; import { useParams } from 'react-router-dom'; @@ -17,11 +19,11 @@ function SingleAlgorithmLayout() { const selectedAlgo = algoList.find(({ name }) => name === algoName) ?? algoList[0]; - const { onComplete, isComplete } = useCompletion(1, reset); useEffect(() => { if (isComplete) { + toast.success(sortCompletionMessage); dispatch(setIsPlaying(null)); } }, [dispatch, isComplete]);