commit cc0d960bdf5255e666ab5e5b1d64f857fcd774ec Author: GarandPLG Date: Wed Oct 16 21:33:12 2024 +0200 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..f311aa4 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json.schemastore.org/prettierrc", + "semi": true, + "tabWidth": 2, + "singleQuote": true, + "printWidth": 100, + "trailingComma": "none", + "useTabs": true, + "arrowParens": "avoid", + "bracketSpacing": true, + "proseWrap": "always", + "htmlWhitespaceSensitivity": "strict", + "endOfLine": "lf" +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..74872fd --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: + +- Configure the top-level `parserOptions` property like this: + +```js +export default tseslint.config({ + languageOptions: { + // other options... + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, +}) +``` + +- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` +- Optionally add `...tseslint.configs.stylisticTypeChecked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: + +```js +// eslint.config.js +import react from 'eslint-plugin-react' + +export default tseslint.config({ + // Set the react version + settings: { react: { version: '18.3' } }, + plugins: { + // Add the react plugin + react, + }, + rules: { + // other rules... + // Enable its recommended rules + ...react.configs.recommended.rules, + ...react.configs['jsx-runtime'].rules, + }, +}) +``` diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000..3e70ce9 Binary files /dev/null and b/bun.lockb differ diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..092408a --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +) diff --git a/package.json b/package.json new file mode 100644 index 0000000..e944eca --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "wierza-hanoi", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "format": "prettier --write src/", + "preview": "vite preview" + }, + "dependencies": { + "@popperjs/core": "^2.11.8", + "bootstrap": "^5.3.3", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "sass": "^1.79.5" + }, + "devDependencies": { + "@eslint/js": "^9.11.1", + "@types/react": "^18.3.10", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react-swc": "^3.5.0", + "eslint": "^9.11.1", + "eslint-plugin-react-hooks": "^5.1.0-rc.0", + "eslint-plugin-react-refresh": "^0.4.12", + "globals": "^15.9.0", + "prettier": "^3.3.3", + "typescript": "^5.5.3", + "typescript-eslint": "^8.7.0", + "vite": "^5.4.8" + } +} diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..0504e3b --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,56 @@ +import { useState } from 'react'; +import Tower from './components/Tower'; +import { Disk } from './types'; + +const App = () => { + const [towers, setTowers] = useState([ + [ + { size: 5, id: 5 }, + { size: 4, id: 4 }, + { size: 3, id: 3 }, + { size: 2, id: 2 }, + { size: 1, id: 1 } + ], + [], + [] + ]); + + const moveDisk = (fromTower: number, toTower: number, diskId: number) => { + setTowers(prevTowers => { + const newTowers = [...prevTowers]; + const diskIndex = newTowers[fromTower].findIndex(disk => disk.id === diskId); + const diskToMove = newTowers[fromTower][diskIndex]; + + if (diskIndex !== 0) return prevTowers; + + const targetTower = newTowers[toTower]; + + if (targetTower.length > 0 && targetTower[0].size < diskToMove.size) return prevTowers; + + newTowers[fromTower] = newTowers[fromTower].filter(disk => disk.id !== diskId); + newTowers[toTower] = [diskToMove, ...newTowers[toTower]]; + + return newTowers; + }); + }; + + return ( +
+

Wieża Hanoi

+
+ {towers.map((tower, index) => ( +
+ i !== index)} + /> +
+ ))} +
+
+ ); +}; + +export default App; diff --git a/src/components/Disk.tsx b/src/components/Disk.tsx new file mode 100644 index 0000000..0a3078f --- /dev/null +++ b/src/components/Disk.tsx @@ -0,0 +1,35 @@ +// components/Disk.tsx +import { FC } from 'react'; +import { DiskProps } from '../types'; + +const DiskComponent: FC = ({ disk, fromTower, otherTowers, onMove }) => { + const width = 50 + disk.size * 30; + + return ( +
+ {disk.size} +
+ {otherTowers.map(toTower => ( + + ))} +
+
+ ); +}; + +export default DiskComponent; diff --git a/src/components/Tower.tsx b/src/components/Tower.tsx new file mode 100644 index 0000000..45b1888 --- /dev/null +++ b/src/components/Tower.tsx @@ -0,0 +1,25 @@ +// components/Tower.tsx +import { FC } from 'react'; +import { TowerProps } from '../types'; +import DiskComponent from './Disk'; + +const Tower: FC = ({ disks, towerIndex, onMove, otherTowers }) => { + return ( +
+

Wieża {towerIndex + 1}

+
+ {disks.map(disk => ( + + ))} +
+
+ ); +}; + +export default Tower; diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..02e54ba --- /dev/null +++ b/src/index.html @@ -0,0 +1,13 @@ + + + + + + + Wierza Hanoi - Kacper Pluciński + + +
+ + + diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..70bd065 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; +import App from './App.tsx'; +import './scss/styles.scss'; + +createRoot(document.getElementById('root')!).render( + + + +); diff --git a/src/public/vite.svg b/src/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/src/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/scss/styles.scss b/src/scss/styles.scss new file mode 100644 index 0000000..7db883d --- /dev/null +++ b/src/scss/styles.scss @@ -0,0 +1,21 @@ +@import 'bootstrap/scss/bootstrap'; + +.tower { + display: flex; + flex-direction: column-reverse; + align-items: center; + border: 1px solid #ddd; + padding: 20px; + min-height: 300px; + background-color: #f8f9fa; +} + +.disk { + display: flex; + justify-content: center; + align-items: center; + margin: 5px 0; + border-radius: 5px; + color: white; + font-weight: bold; +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..1c17514 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,18 @@ +export interface Disk { + size: number; + id: number; +} + +export interface DiskProps { + disk: Disk; + fromTower: number; + otherTowers: number[]; + onMove: (from: number, to: number, diskId: number) => void; +} + +export interface TowerProps { + disks: Disk[]; + towerIndex: number; + onMove: (from: number, to: number, diskId: number) => void; + otherTowers: number[]; +} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..f0a2350 --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..0d3d714 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..68a7fa1 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,9 @@ +import path from 'path'; +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react-swc'; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + root: 'src' +});