diff --git a/AGENTS.md b/AGENTS.md index 8f3238cc..4942f4df 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,10 +10,10 @@ This project prefers a highly componentized React codebase that avoids duplicate - **Styling**: Use Tailwind CSS utility classes. Share common styling through base components rather than repeating class strings. - **Git**: Do not commit .png files - **Formatting**: Code is formatted with Prettier using tabs. Run `npx prettier --write` before committing. Don't add comments to code unless absolutely necessary. -- **Testing**: After changes, run `yarn test:codex` from the repository root to ensure all tests pass. - **Type Safety**: You are not allowed to use `any` or `unknown`. -- **Redux**: Compose selectors and helpers rather than copy/pasting logic. +- **Redux**: Compose selectors and helpers rather than copy/pasting logic. UI components should avoid data manipulation—use Redux selectors to transform and format data instead of doing it in components. - **Error Handling**: Keep error handling reasonable but not excessive. This is a small app - simple null checks and basic 404s are fine. Don't over-engineer with detailed error types for every edge case. - **Unit Tests**: Write unit tests for important service functions, especially those involving business logic or data transformations. +- **Testing**: After changes, run `yarn test:codex` from the repository root to ensure all tests pass. Follow these guidelines to keep the codebase clean and maintainable. diff --git a/apps/react/src/App.tsx b/apps/react/src/App.tsx index 1d4f06d7..f9b33dba 100644 --- a/apps/react/src/App.tsx +++ b/apps/react/src/App.tsx @@ -18,6 +18,7 @@ import { useDarkMode } from './utils/useDarkMode'; import { DeckStatsScreen } from './screens/DeckStatsScreen/DeckStatsScreen'; import { AccountScreen } from './screens/AccountScreen/AccountScreen'; import { AttemptHistoryScreen } from './screens/AttemptHistoryScreen/AttemptHistoryScreen'; +import { StreakActivityScreen } from './screens/StreakActivityScreen/StreakActivityScreen'; import { useAppDispatch } from 'MemoryFlashCore/src/redux/store'; import { refreshUser } from 'MemoryFlashCore/src/redux/actions/refresh-user-action'; @@ -81,6 +82,10 @@ export default function App() { path="/study/:deckId/stats" element={} />} /> + } />} + /> } />} diff --git a/apps/react/src/components/StreakChip.tsx b/apps/react/src/components/StreakChip.tsx index 5c6440ef..41fdd28a 100644 --- a/apps/react/src/components/StreakChip.tsx +++ b/apps/react/src/components/StreakChip.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useRef, useState } from 'react'; +import { Link } from 'react-router-dom'; import clsx from 'clsx'; import { useAppSelector } from 'MemoryFlashCore/src/redux/store'; @@ -25,10 +26,12 @@ export const StreakChip: React.FC = ({ className }) => { }, [count]); return ( -
= ({ className }) => { > 🔥 {displayCount} -
+ ); }; diff --git a/apps/react/src/components/feedback/NetworkStateWrapper.tsx b/apps/react/src/components/feedback/NetworkStateWrapper.tsx index 4601f2c2..b76bf46e 100644 --- a/apps/react/src/components/feedback/NetworkStateWrapper.tsx +++ b/apps/react/src/components/feedback/NetworkStateWrapper.tsx @@ -20,12 +20,13 @@ export const NetworkStateWrapper: React.FC = ({ const showSpinner = isLoading && (showSpinnerWhen === 'always' || (showSpinnerWhen === 'no-children' && !hasData)); + const showChildren = !isLoading || hasData; return ( <> - {children} + {showChildren && children} ); }; diff --git a/apps/react/src/components/inputs/BaseTextArea.tsx b/apps/react/src/components/inputs/BaseTextArea.tsx index f8e755ac..b3b998c1 100644 --- a/apps/react/src/components/inputs/BaseTextArea.tsx +++ b/apps/react/src/components/inputs/BaseTextArea.tsx @@ -6,7 +6,7 @@ export const BaseTextArea = React.forwardRef (