@@ -247,6 +247,21 @@ export const useAdminDeleteResource = () => {
247247 },
248248 });
249249};
250+
251+ export const useAdminCreatePostSection = () => {
252+ const queryClient = useQueryClient();
253+
254+ return useMutation<CreatePostSectionResponse, Error, CreatePostSectionInput>({
255+ mutationFn: async (data) => {
256+ return sdk.admin.pageBuilder.createPostSection(data);
257+ },
258+ mutationKey: QUERY_KEYS.POST_SECTIONS,
259+ onSuccess: () => {
260+ queryClient.invalidateQueries({ queryKey: QUERY_KEYS.POST_SECTIONS });
261+ queryClient.invalidateQueries({ queryKey: QUERY_KEYS.POSTS });
262+ },
263+ });
264+ };
250265```
251266
252267### Query Hooks
@@ -394,6 +409,22 @@ export const QUERY_KEYS = {
394409 AUTHORS: ['authors'],
395410 TAGS: ['tags'],
396411} as const;
412+
413+ // Always invalidate related queries in mutations
414+ export const useAdminCreatePostSection = () => {
415+ const queryClient = useQueryClient();
416+
417+ return useMutation<CreatePostSectionResponse, Error, CreatePostSectionInput>({
418+ mutationFn: async (data) => {
419+ return sdk.admin.pageBuilder.createPostSection(data);
420+ },
421+ mutationKey: QUERY_KEYS.POST_SECTIONS,
422+ onSuccess: () => {
423+ queryClient.invalidateQueries({ queryKey: QUERY_KEYS.POST_SECTIONS });
424+ queryClient.invalidateQueries({ queryKey: QUERY_KEYS.POSTS });
425+ },
426+ });
427+ };
397428```
398429
399430### Error Handling
@@ -609,28 +640,33 @@ describe('useAdminCreateResource', () => {
609640});
610641```
611642
612- ## Common Anti-Patterns to Avoid
643+ ## Verification Checklist
613644
614- ❌ **Don't**: Use inline styles or CSS-in-JS
615- ✅ **Do**: Use Tailwind CSS classes and Medusa UI components
645+ Before submitting admin UI code, ensure:
616646
617- ❌ **Don't**: Fetch data directly in components
618- ✅ **Do**: Use custom hooks with TanStack Query
647+ ### State Management
648+ - [ ] All mutations invalidate related query keys using `QUERY_KEYS`
649+ - [ ] Query keys are centralized and use consistent naming
650+ - [ ] Loading and error states are properly handled
651+ - [ ] Optimistic updates are implemented where appropriate
619652
620- ❌ **Don't**: Mutate state directly
621- ✅ **Do**: Use React Hook Form for form state and TanStack Query for server state
622-
623- ❌ **Don't**: Create deeply nested component hierarchies
624- ✅ **Do**: Use composition and context for state sharing
625-
626- ❌ **Don't**: Skip error boundaries and error handling
627- ✅ **Do**: Implement proper error handling with toast notifications
653+ ### Component Patterns
654+ - [ ] Event handlers use `stopPropagation()` for nested actions
655+ - [ ] Components use proper TypeScript generics for reusability
656+ - [ ] Form validation uses Zod schemas with proper error handling
657+ - [ ] Accessibility attributes (ARIA labels, roles) are included
628658
629- ❌ **Don't**: Use any types or skip TypeScript
630- ✅ **Do**: Define strict interfaces and use proper typing
659+ ### Performance
660+ - [ ] Components use `memo()` for expensive renders
661+ - [ ] Event handlers are wrapped in `useCallback()` when needed
662+ - [ ] Heavy computations use `useMemo()`
663+ - [ ] Query data is properly selected to minimize re-renders
631664
632- ❌ **Don't**: Forget accessibility attributes
633- ✅ **Do**: Include proper ARIA labels, roles, and keyboard navigation
665+ ### Error Handling
666+ - [ ] All async operations have try-catch blocks
667+ - [ ] User-friendly error messages are displayed via toast
668+ - [ ] Network errors are handled gracefully
669+ - [ ] Form validation errors are displayed inline
634670
635671## Dependencies
636672
@@ -644,3 +680,80 @@ Required packages for Medusa v2 admin development:
644680- `clsx`: Conditional class names
645681- `react-router-dom`: Client-side routing
646682
683+ ## Common Anti-Patterns to Avoid
684+
685+ ❌ **Don't**: Fetch data directly in components
686+ ```typescript
687+ // Bad - direct API calls in components
688+ const MyComponent = () => {
689+ const [data, setData] = useState(null);
690+ useEffect(() => {
691+ fetch('/api/data').then(res => setData(res));
692+ }, []);
693+ };
694+ ```
695+
696+ ✅ **Do**: Use custom hooks with TanStack Query
697+ ```typescript
698+ // Good - use query hooks
699+ const MyComponent = () => {
700+ const { data, isLoading } = useAdminListResources();
701+ };
702+ ```
703+
704+ ❌ **Don't**: Skip event.stopPropagation() in nested actions
705+ ```typescript
706+ // Bad - events bubble up unintentionally
707+ const handleDelete = async () => {
708+ await deleteItem(id); // Parent onClick also fires
709+ };
710+ ```
711+
712+ ✅ **Do**: Use stopPropagation for nested actions
713+ ```typescript
714+ // Good - prevent event bubbling
715+ const handleDelete = async (event: MouseEvent) => {
716+ event.stopPropagation();
717+ await deleteItem(id);
718+ };
719+ ```
720+
721+ ❌ **Don't**: Forget to invalidate query cache
722+ ```typescript
723+ // Bad - stale data after mutations
724+ const { mutate } = useMutation({
725+ mutationFn: createResource,
726+ // Missing onSuccess invalidation
727+ });
728+ ```
729+
730+ ✅ **Do**: Always invalidate related queries
731+ ```typescript
732+ // Good - fresh data after mutations
733+ const { mutate } = useMutation({
734+ mutationFn: createResource,
735+ onSuccess: () => {
736+ queryClient.invalidateQueries({ queryKey: QUERY_KEYS.RESOURCES });
737+ },
738+ });
739+ ```
740+
741+ ### Component Files
742+ - Use PascalCase for component files: `PostSectionListItem.tsx`
743+ - Co-locate related files in feature directories
744+ - Separate concerns: components, hooks, types, and tests
745+
746+ #### Hook Files
747+ - Group by functionality: `post-sections-mutations.ts`, `post-sections-queries.ts`
748+ - Use descriptive names: `useAdminCreatePostSection`
749+ - Export related hooks from index files
750+
751+ #### Type Files
752+ - Define interfaces close to usage
753+ - Use barrel exports for shared types
754+ - Prefer type-only imports: `import type { User } from './types'`
755+
756+ #### Test Files
757+ - Mirror source structure: `components/__tests__/Button.test.tsx`
758+ - Use descriptive test names
759+ - Group related tests in describe blocks
0 commit comments