Coding practices for frontend development in Atomic CRM. Use when creating or modifying React components, forms, list pages, detail views, filters, data fetching, or responsive layouts.
80
—
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
Reference for the conventions a frontend change must follow. This is a reference skill, not a step sequence — read the relevant section before writing code, then verify against the checklist at the end. The frontend uses ra-core (react-admin headless) for data fetching, routing, and CRUD logic, with shadcn-admin-kit and shadcn/ui for the UI layer.
Not for backend/schema work — see Skill({skill: "backend-dev"}).
Not for theming/colors — see Skill({skill: "shadcn-customization"}).
TextInput, SelectInput, ReferenceInput, etc.) from @/components/admin/, not from shadcn/ui directly. The admin layer wraps shadcn with ra-core integration (labels, validation, data binding).Card, Button, Badge, Sheet, etc.) from @/components/ui/.useConfigurationContext(), never hardcoded.Each resource follows this file structure (e.g. contacts/):
ContactList.tsx — list page (desktop + mobile variants)ContactShow.tsx — detail viewContactEdit.tsx / ContactCreate.tsx — form pagesContactInputs.tsx — shared form fields reused between create and editindex.tsx — exports { list, show, edit, create, recordRepresentation }Resources are registered in root/CRM.tsx via <Resource name="contacts" {...contacts} />.
useListContext(), useShowContext(), useGetList(), useGetOne(), useGetIdentity().useQuery/useMutation with useDataProvider<CrmDataProvider>() (e.g. dataProvider.getActivityLog() in ActivityLog.tsx, dataProvider.salesCreate() in SalesCreate.tsx).Form from ra-core + FormToolbar for submit/cancel actions.Form uses React Hook Form under the hood. Use useFormContext() for imperative operations (setValue, reset, getValues).CreateBase/EditBase with Card (e.g. contacts), or Dialog (e.g. deals).CreateSheet/EditSheet from misc/ (e.g. notes, tasks).ContactIdentityInputs, ContactPositionInputs).ToggleFilterButton / ActiveFilterButton components for filter UI.useIsMobile() to branch.MobileHeader/MobileContent.InfiniteListBase for scroll pagination.TextInput/SelectInput/etc. directly from @/components/ui/ instead of @/components/admin/.useConfigurationContext().root/CRM.tsx.useIsMobile() branch.@/components/admin/, pure UI from @/components/ui/.useConfigurationContext() — nothing hardcoded.root/CRM.tsx.Skill({skill: "e2e-conventions"})).dce557e
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.