| alwaysApply | true |
|---|
- When being asked to create a new alert make sure to scan the following files to get the context:
- @IdleonToolbox/utility/migrations.js
- @IdleonToolbox/pages/dashboard.jsx
- @IdleonToolbox/components/dashboard/Account.jsx
- @IdleonToolbox/components/dashboard/Characters.jsx
- @IdleonToolbox/utility/dashboard/account.js
- @IdleonToolbox/utility/dashboard/characters.js
- If the "baseTrackers" object version in dashboard.jsx was already updated in the current changes, don't update it, if it didn't make sure to bump it one version and add the relevant migration.
- When being asked to create new page, make sure to add it to the correct folder path, when unsure, ask.
- Update the relevant PAGES path at @IdleonToolbox/components/constants.jsx
- In case tabs are being added to the page, make sure to update the tabs array as well.
- Every new page should have an icon, if an icon is not being provided, you can use "/data/ClassIconsNA2.png" as a temporary file.
- When being asked to reformat, validate or restructure an obuscated code, make sure to look at @IdleonToolbox/parsers for more context.
- Always prefer using existing functions.
- Always use readable and maintainable code.
- For more context you can query the @IdleonToolbox/data/website-data.json file - which contains most of the data relevant to the project.
- Few examples of obfuscated function vs existing one:
m._customBlock_Summoning("WinBonus", 27, 0)->getWinnerBonus(account, '<x Amber Gain')a.engine.getGameAttribute("OptionsListAccount")[478]->account?.accountOptions?.[478]m._customBlock_Summoning2("MeritocBonusz", 17, 0)->getMeritocracyBonus(account, 17)a.engine.getGameAttribute("DNSM").h.AlchBubbles.h.M11->getBubbleBonus(account, 'DEEP_DEPTH', false)
When testing add "http://localhost:3001?demo=true" to be able to access all pages without login in
This is a gradual TypeScript migration. The codebase is mixed JS/TS:
- Parsers (
parsers/) — TypeScript (.ts). All new parsers must be.ts. - Components (
components/) — JavaScript (.jsx). Keep them.jsxunless explicitly asked to migrate. - Utilities/hooks/services — mostly
.js, migrate to.tsonly when requested.
- Auto-generated — do not edit manually:
parsers/generated-types.ts— parsedAccountandCharactershapes (generated via Jest)parsers/generated-firebase-types.ts— raw Firebase data types (IdleonData,ServerVars, etc.)data/website-data.d.json.ts— types forwebsite-data.json(generated byz-processing/typeGenerator.js)
- Canonical imports: use
import type { IdleonData, Account } from './types'(barrel file inparsers/types.ts) - Ambient globals:
custom.tsdeclaresAccount,Character,IdleonDataas global interfaces so.js/.jsxfiles can use them without imports. Prefer explicit imports in.tsfiles.
- Export interfaces for return types (e.g.,
export interface Achievement { ... }) - Use
typeimports:import type { IdleonData, Account } from './types' - Signature:
export const getXxx = (idleonData: IdleonData, account: Account, ...): ReturnType => { ... } - Internal helper params can use
anywhere full typing is impractical
Configured in both tsconfig.json and next.config.js:
@components/*→components/*@parsers/*→parsers/*@hooks/*→hooks/*@utility/*→utility/*@website-data→data/website-data.json
All user-facing dates and times must respect user preferences (DD/MM vs MM/DD, 24h vs 12h). Preferences are stored in localStorage (pref-dateFormat, pref-timeFormat) and exposed via PreferencesContext.
In React components, use one of these hooks — never hardcode format strings like 'dd/MM/yyyy HH:mm:ss':
useFormatDate(@hooks/useFormatDate) — returnsformatDate(dateMs, options?). Use for direct date formatting.- Options:
{ showSeconds, shortYear, timeOnly }(all defaultfalseexceptshowSecondswhich defaultstrue) - Example:
formatDate(timestamp),formatDate(date, { timeOnly: true }),formatDate(date, { shortYear: true, showSeconds: false })
- Options:
useRealDate(@hooks/useRealDate) — returns(ms, shouldFormat?) => string. Drop-in replacement forgetRealDateInMs. Handles the "X days" fallback for non-date values.- Example:
const getRealDateInMs = useRealDate();then use like before.
- Example:
Outside React (parsers, utilities): getRealDateInMs in utility/helpers.js accepts an optional formatString parameter. No React components should import this directly — use the hooks instead.
Formats that are intentionally unambiguous (e.g., 'MMM do, yyyy' showing month names) do not need migration.
Data export formats (e.g., clipboard export, image footers in Breakdown.hook.js) may use the preference system too, so the exported data matches what the user sees on screen.
This project uses React Compiler (reactCompiler: true in next.config.js), so manual memoization with useMemo and useCallback is generally unnecessary. The compiler automatically optimizes component re-renders.
Some fields produced by serializeData depend on values that are computed during the same
serialization step.
For this reason, serializeData is intentionally executed multiple times (currently 3 passes).
Each pass may unlock additional derived values for the next one.
By the final pass, all cascading and inter-dependent calculations are considered stabilized, and code is allowed to rely on values that were produced in earlier passes.