Cleans up readme and some styling.

This commit is contained in:
Drew Haven 2025-09-02 17:59:48 -07:00
parent 181805fcab
commit 64f00b12de
6 changed files with 66 additions and 82 deletions

View File

@ -1,69 +1,22 @@
# React + TypeScript + Vite
# WoW Gear Finder
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
A simple app for tracking what gear you have and so seeing what gear you might still get as upgrades.
Currently, two official plugins are available:
Currently all data is stored locally in your browser. There is no server-side data.
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
## Running the app
## Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
```js
export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
...tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
...tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
...tseslint.configs.stylisticTypeChecked,
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```bash
npm run dev
```
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
## Downloading Item Data
```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
Item data is fetched from Wowhead APIs. You will need to get the item IDs from somewhere though, e.g. Wowhead searches. Then there is a script that will download the data and format it into `./fetched-items.json`
For example, to fetch items 237680 and 237681 and mark their source as "Tier" you would run:
```bash
npm run fetch-items "Tier" 237680 237681
export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```

View File

@ -1,6 +0,0 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
width: 100%;
}

20
src/App.module.css Normal file
View File

@ -0,0 +1,20 @@
.appPanels {
display: grid;
gap: 16px;
}
@media (min-width: 768px) {
.appPanels {
grid-template-columns: 1fr 1fr;
}
}
@media (max: 768px) {
.appPanels {
grid-template-columns: 1fr;
}
}
.panel {
flex-grow: 1;
}

View File

@ -1,5 +1,5 @@
import { useEffect, useReducer } from "react";
import "./App.css";
import styles from "./App.module.css";
import { Equipment } from "./components/Equipment";
import { SourceList } from "./components/SourceList";
import { StateContext } from "./lib/context/StateContext";
@ -25,9 +25,10 @@ function App() {
dispatch({
action: "loadState",
state: {
equipedItems: [{ id: 219309 as ItemId, quality: "champion" }],
equipedItems: [],
bisList: [],
weaponConfig: WeaponConfig.TwoHander,
spec: 268,
},
});
}
@ -49,17 +50,25 @@ function App() {
}}
>
<h1>WoW Gear Finder</h1>
<h2>Config</h2>
<WeaponConfigPicker />
<SpecSelector />
<h2>Equipment</h2>
<Equipment
state={state}
onEquip={(item) => dispatch({ action: "equipItem", item })}
onUnequip={(item) => dispatch({ action: "unequipItem", item })}
/>
<h2>Upgrades</h2>
<SourceList state={state} />
<div>
<h2>Config</h2>
<WeaponConfigPicker />
<SpecSelector />
</div>
<div className={styles.appPanels}>
<div className={styles.panel}>
<h2>Equipment</h2>
<Equipment
state={state}
onEquip={(item) => dispatch({ action: "equipItem", item })}
onUnequip={(item) => dispatch({ action: "unequipItem", item })}
/>
</div>
<div className={styles.panel}>
<h2>Upgrades</h2>
<SourceList state={state} />
</div>
</div>
</StateContext.Provider>
);
}

View File

@ -67,3 +67,10 @@ button:focus-visible {
background-color: #f9f9f9;
}
}
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
width: 100%;
}

View File

@ -135,7 +135,8 @@ export const Spec = {
Havoc: 577,
Vengeance: 581,
},
};
} as const;
export type Spec =
(typeof Spec)[keyof typeof Spec][keyof (typeof Spec)[keyof typeof Spec]];
type Values<T> = T extends object ? Values<T[keyof T]> : T;
export type Spec = Values<typeof Spec>;