From 9a5b6e9f9251a056afa60acefa16be3193786433 Mon Sep 17 00:00:00 2001 From: ErwannRousseau Date: Fri, 21 Mar 2025 18:33:11 +0100 Subject: [PATCH 1/5] feat: add prop-types --- src/components/Store.jsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/Store.jsx b/src/components/Store.jsx index 87d88af..1ce01b0 100644 --- a/src/components/Store.jsx +++ b/src/components/Store.jsx @@ -1,5 +1,6 @@ import "./Store.css"; import items from "@/items.json"; +// import PropTypes from "prop-types"; export function Store({ lines, onBuy }) { const canBuy = (item) => { @@ -25,3 +26,8 @@ export function Store({ lines, onBuy }) { ); } + +// Store.propTypes = { +// lines: PropTypes.number.isRequired, +// onBuy: PropTypes.func.isRequired, +// }; From 2dc0fba2a8ade9054f46e11bf29aac8845df847e Mon Sep 17 00:00:00 2001 From: ErwannRousseau Date: Fri, 21 Mar 2025 19:27:42 +0100 Subject: [PATCH 2/5] feat: Typescript setup --- package.json | 8 ++-- pnpm-lock.yaml | 38 ++++++++++++++++--- src/{Checkbox.jsx => Checkbox.tsx} | 0 ...arentComponent.jsx => ParentComponent.tsx} | 0 src/components/{Game.jsx => Game.tsx} | 2 +- src/components/{Gitcoin.jsx => Gitcoin.tsx} | 0 src/components/{Office.jsx => Office.tsx} | 0 src/components/{Score.jsx => Score.tsx} | 0 src/components/{Store.jsx => Store.tsx} | 0 src/{main.jsx => main.tsx} | 2 +- src/vite-env.d.ts | 1 + tsconfig.app.json | 30 +++++++++++++++ tsconfig.json | 7 ++++ tsconfig.node.json | 24 ++++++++++++ vite.config.js => vite.config.ts | 0 15 files changed, 101 insertions(+), 11 deletions(-) rename src/{Checkbox.jsx => Checkbox.tsx} (100%) rename src/{ParentComponent.jsx => ParentComponent.tsx} (100%) rename src/components/{Game.jsx => Game.tsx} (97%) rename src/components/{Gitcoin.jsx => Gitcoin.tsx} (100%) rename src/components/{Office.jsx => Office.tsx} (100%) rename src/components/{Score.jsx => Score.tsx} (100%) rename src/components/{Store.jsx => Store.tsx} (100%) rename src/{main.jsx => main.tsx} (93%) create mode 100644 src/vite-env.d.ts create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json rename vite.config.js => vite.config.ts (100%) diff --git a/package.json b/package.json index b538965..876a41c 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "vite", - "build": "vite build", + "build": "tsc -b && vite build", "lint": "eslint .", "preview": "vite preview" }, @@ -14,10 +14,12 @@ "react-dom": "^19.0.0" }, "devDependencies": { - "@types/react": "^19.0.10", + "@types/node": "^22.13.11", + "@types/react": "^19.0.12", "@types/react-dom": "^19.0.4", "@vitejs/plugin-react": "^4.3.4", + "typescript": "^5.8.2", "vite": "^6.2.0" }, "packageManager": "pnpm@10.6.5+sha512.cdf928fca20832cd59ec53826492b7dc25dc524d4370b6b4adbf65803d32efaa6c1c88147c0ae4e8d579a6c9eec715757b50d4fa35eea179d868eada4ed043af" -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4b9d05e..dc8f7f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,18 +15,24 @@ importers: specifier: ^19.0.0 version: 19.0.0(react@19.0.0) devDependencies: + '@types/node': + specifier: ^22.13.11 + version: 22.13.11 '@types/react': - specifier: ^19.0.10 + specifier: ^19.0.12 version: 19.0.12 '@types/react-dom': specifier: ^19.0.4 version: 19.0.4(@types/react@19.0.12) '@vitejs/plugin-react': specifier: ^4.3.4 - version: 4.3.4(vite@6.2.2) + version: 4.3.4(vite@6.2.2(@types/node@22.13.11)) + typescript: + specifier: ^5.8.2 + version: 5.8.2 vite: specifier: ^6.2.0 - version: 6.2.2 + version: 6.2.2(@types/node@22.13.11) packages: @@ -391,6 +397,9 @@ packages: '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/node@22.13.11': + resolution: {integrity: sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==} + '@types/react-dom@19.0.4': resolution: {integrity: sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==} peerDependencies: @@ -516,6 +525,14 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + typescript@5.8.2: + resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true @@ -854,6 +871,10 @@ snapshots: '@types/estree@1.0.6': {} + '@types/node@22.13.11': + dependencies: + undici-types: 6.20.0 + '@types/react-dom@19.0.4(@types/react@19.0.12)': dependencies: '@types/react': 19.0.12 @@ -862,14 +883,14 @@ snapshots: dependencies: csstype: 3.1.3 - '@vitejs/plugin-react@4.3.4(vite@6.2.2)': + '@vitejs/plugin-react@4.3.4(vite@6.2.2(@types/node@22.13.11))': dependencies: '@babel/core': 7.26.10 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 6.2.2 + vite: 6.2.2(@types/node@22.13.11) transitivePeerDependencies: - supports-color @@ -993,18 +1014,23 @@ snapshots: source-map-js@1.2.1: {} + typescript@5.8.2: {} + + undici-types@6.20.0: {} + update-browserslist-db@1.1.3(browserslist@4.24.4): dependencies: browserslist: 4.24.4 escalade: 3.2.0 picocolors: 1.1.1 - vite@6.2.2: + vite@6.2.2(@types/node@22.13.11): dependencies: esbuild: 0.25.1 postcss: 8.5.3 rollup: 4.36.0 optionalDependencies: + '@types/node': 22.13.11 fsevents: 2.3.3 yallist@3.1.1: {} diff --git a/src/Checkbox.jsx b/src/Checkbox.tsx similarity index 100% rename from src/Checkbox.jsx rename to src/Checkbox.tsx diff --git a/src/ParentComponent.jsx b/src/ParentComponent.tsx similarity index 100% rename from src/ParentComponent.jsx rename to src/ParentComponent.tsx diff --git a/src/components/Game.jsx b/src/components/Game.tsx similarity index 97% rename from src/components/Game.jsx rename to src/components/Game.tsx index 2d309d8..2e38370 100644 --- a/src/components/Game.jsx +++ b/src/components/Game.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "react"; import "./Game.css"; -import items from "../items.json"; +import items from "@/items.json"; import { Gitcoin } from "./Gitcoin"; import { Office } from "./Office"; import { Score } from "./Score"; diff --git a/src/components/Gitcoin.jsx b/src/components/Gitcoin.tsx similarity index 100% rename from src/components/Gitcoin.jsx rename to src/components/Gitcoin.tsx diff --git a/src/components/Office.jsx b/src/components/Office.tsx similarity index 100% rename from src/components/Office.jsx rename to src/components/Office.tsx diff --git a/src/components/Score.jsx b/src/components/Score.tsx similarity index 100% rename from src/components/Score.jsx rename to src/components/Score.tsx diff --git a/src/components/Store.jsx b/src/components/Store.tsx similarity index 100% rename from src/components/Store.jsx rename to src/components/Store.tsx diff --git a/src/main.jsx b/src/main.tsx similarity index 93% rename from src/main.jsx rename to src/main.tsx index b69ab72..71f449f 100644 --- a/src/main.jsx +++ b/src/main.tsx @@ -7,6 +7,6 @@ root.render( <> {/* 💡 Uncomment the following to enable the Game component */} - {/* */} + , ); 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..0592374 --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "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, + "noUncheckedSideEffectImports": true, + + "paths": { + "@/*": ["./src/*"] + } + }, + "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..db0becc --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "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, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.js b/vite.config.ts similarity index 100% rename from vite.config.js rename to vite.config.ts From 2b95f3e63befd13bf89031b31982bcf5c9a10bd4 Mon Sep 17 00:00:00 2001 From: ErwannRousseau Date: Mon, 24 Mar 2025 16:05:59 +0100 Subject: [PATCH 3/5] feat: adding TypeScript types --- src/components/Game.tsx | 11 ++++++++--- src/components/Gitcoin.tsx | 6 +++++- src/components/Office.tsx | 8 +++++++- src/components/Score.tsx | 7 ++++++- src/components/Store.tsx | 10 ++++++++-- src/main.tsx | 13 +++++++------ src/types.ts | 9 +++++++++ 7 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 src/types.ts diff --git a/src/components/Game.tsx b/src/components/Game.tsx index 2e38370..1e15bb5 100644 --- a/src/components/Game.tsx +++ b/src/components/Game.tsx @@ -1,6 +1,7 @@ import { useEffect, useState } from "react"; import "./Game.css"; import items from "@/items.json"; +import type { Item, OwnedItems } from "@/types"; import { Gitcoin } from "./Gitcoin"; import { Office } from "./Office"; import { Score } from "./Score"; @@ -9,7 +10,8 @@ import { Store } from "./Store"; export function Game() { const [lines, setLines] = useState(0); const [linesPerMillisecond, setLinesPerMillisecond] = useState(0); - const [ownedItems, setOwnedItems] = useState({}); + + const [ownedItems, setOwnedItems] = useState({}); useEffect(() => { const interval = setInterval(() => { @@ -24,7 +26,10 @@ export function Game() { for (const name of Object.keys(ownedItems)) { const item = items.find((element) => element.name === name); - count += item.linesPerMillisecond * ownedItems[name]; + + if (item != null) { + count += item.linesPerMillisecond * ownedItems[name]; + } } setLinesPerMillisecond(count); @@ -34,7 +39,7 @@ export function Game() { setLines(lines + 1); }; - const handleBuy = (item) => { + const handleBuy = (item: Item) => { setLines(lines - item.price); setOwnedItems({ ...ownedItems, diff --git a/src/components/Gitcoin.tsx b/src/components/Gitcoin.tsx index f18eac6..67c96e9 100644 --- a/src/components/Gitcoin.tsx +++ b/src/components/Gitcoin.tsx @@ -1,7 +1,11 @@ import "./Gitcoin.css"; import githubIcon from "@/assets/github.svg"; -export function Gitcoin({ onClick }) { +type Props = { + onClick: () => void; +}; + +export function Gitcoin({ onClick }: Props) { return ( - ); + ) } diff --git a/src/components/Office.tsx b/src/components/Office.tsx index bd096c1..4b0028c 100644 --- a/src/components/Office.tsx +++ b/src/components/Office.tsx @@ -1,22 +1,24 @@ -import type { OwnedItems } from "@/types"; +import type { OwnedItems } from '@/types' type Props = { - items: OwnedItems; -}; + items: OwnedItems +} export function Office({ items }: Props) { return ( <>

Office

    - {Object.keys(items).map((name) => ( + {Object.keys(items).map(name => (
  • - {items[name]} {name} + {items[name]} + {' '} + {name}
  • ))}
- ); + ) } diff --git a/src/components/Score.tsx b/src/components/Score.tsx index f168d60..7743f72 100644 --- a/src/components/Score.tsx +++ b/src/components/Score.tsx @@ -1,13 +1,20 @@ type Props = { - lines: number; - linesPerSecond: number; -}; + lines: number + linesPerSecond: number +} export function Score({ lines, linesPerSecond }: Props) { return ( <> -

{lines} lines

- per second: {linesPerSecond} +

+ {lines} + {' '} + lines +

+ + per second: + {linesPerSecond} + - ); + ) } diff --git a/src/components/Store.tsx b/src/components/Store.tsx index 7c666bf..8ecf699 100644 --- a/src/components/Store.tsx +++ b/src/components/Store.tsx @@ -1,24 +1,27 @@ -import type { Item } from "@/types"; -import "./Store.css"; -import items from "@/items.json"; +import type { Item } from '@/types' +import './Store.css' +import items from '@/items.json' // import PropTypes from "prop-types"; type Props = { - lines: number; - onBuy: (item: Item) => void; -}; + lines: number + onBuy: (item: Item) => void +} export function Store({ lines, onBuy }: Props) { const canBuy = (item: Item) => { - return lines >= item.price; - }; + return lines >= item.price + } return (
    - {items.map((item) => ( + {items.map(item => (
  • - {item.name} - {item.price} + {item.name} + {' '} + - + {item.price}
  • ))}
- ); + ) } // Store.propTypes = { diff --git a/src/main.tsx b/src/main.tsx index 06691b1..a6f03c9 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,13 +1,13 @@ -import ParentComponent from "@/ParentComponent"; -import { Game } from "@/components/Game"; -import React from "react"; -import { createRoot } from "react-dom/client"; +// import ParentComponent from '@/ParentComponent' +import { Game } from '@/components/Game' +import React from 'react' +import { createRoot } from 'react-dom/client' -const root = createRoot(document.getElementById("root") as HTMLElement); +const root = createRoot(document.getElementById('root') as HTMLElement) root.render( - - {/* 💡 Uncomment the following to enable the Game component */} - {/* */} + {/* 💡 Uncomment comments to enable the ParentComponent, just an example */} + {/* */} + , -); +) diff --git a/src/types.ts b/src/types.ts index e6b0909..a42500c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,9 +1,9 @@ export type Item = { - name: string; - price: number; - linesPerMillisecond: number; -}; + name: string + price: number + linesPerMillisecond: number +} export type OwnedItems = { - [key: string]: number; -}; + [key: string]: number +} diff --git a/vite.config.ts b/vite.config.ts index 356efd0..5faaa7b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,13 +1,13 @@ -import path from "node:path"; -import react from "@vitejs/plugin-react"; -import { defineConfig } from "vite"; +import path from 'node:path' +import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite' // https://vite.dev/config/ export default defineConfig({ plugins: [react()], resolve: { alias: { - "@": path.resolve(__dirname, "./src"), + '@': path.resolve(__dirname, './src'), }, }, -}); +})