Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,24 @@ function App() {
// Sync state and actions from hooks into the zustand store so that
// child components can subscribe to individual slices without a Provider.
useEffect(() => {
useFormStore.setState({
const nextState = {
username, startDate, endDate, githubToken, apiMode, searchText,
loading, loadingProgress, error,
searchItemsCount, eventsCount, rawEventsCount,
setUsername, setStartDate, setEndDate, setGithubToken, setApiMode, setSearchText,
handleSearch, validateUsernameFormat, addAvatarsToCache,
});
};
const currentState = useFormStore.getState() as typeof nextState;
const changedState = (Object.keys(nextState) as (keyof typeof nextState)[]).reduce(
(acc, key) => {
if (currentState[key] !== nextState[key]) acc[key] = nextState[key] as never;
return acc;
},
{} as Partial<typeof nextState>
);
if (Object.keys(changedState).length > 0) {
useFormStore.setState(changedState);
}
}, [
username, startDate, endDate, githubToken, apiMode, searchText,
loading, loadingProgress, error,
Expand Down
3 changes: 3 additions & 0 deletions src/components/__tests__/Summary.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ const mockFormStore = {
endDate: '2024-01-31',
username: 'testuser',
apiMode: 'summary' as const,
searchText: '',
setUsername: vi.fn(),
setStartDate: vi.fn(),
setEndDate: vi.fn(),
setGithubToken: vi.fn(),
setApiMode: vi.fn(),
setSearchText: vi.fn(),
handleSearch: vi.fn(),
validateUsernameFormat: vi.fn(),
addAvatarsToCache: vi.fn(),
loading: false,
loadingProgress: '',
error: null,
Expand Down
10 changes: 5 additions & 5 deletions src/store/useFormStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface FormStoreActions {
setGithubToken: (token: string) => void;
setApiMode: (mode: ApiMode) => void;
setSearchText: (text: string) => void;
handleSearch: () => void;
handleSearch: () => Promise<void>;
validateUsernameFormat: (username: string) => void;
addAvatarsToCache: (avatarUrls: { [username: string]: string }) => void;
}
Expand All @@ -39,9 +39,9 @@ type FormStore = FormStoreState & FormStoreActions;
/**
* Zustand store replacing the former React Context (FormContext).
*
* State values and action callbacks are synced from App.tsx via
* `useFormStoreSync` so that the existing hooks remain the source of truth
* while consumers get fine-grained subscriptions without a Provider.
* State values and action callbacks are synced from App.tsx via a `useEffect`
* hook so that the existing hooks remain the source of truth while consumers
* get fine-grained subscriptions without a Provider.
*/
const useFormStore = create<FormStore>()(() => ({
// State defaults
Expand All @@ -65,7 +65,7 @@ const useFormStore = create<FormStore>()(() => ({
setGithubToken: () => {},
setApiMode: () => {},
setSearchText: () => {},
handleSearch: () => {},
handleSearch: () => Promise.resolve(),
validateUsernameFormat: () => {},
addAvatarsToCache: () => {},
}));
Expand Down