Frontend — React + Mantine + Product Thinking
Core Principle
Understand the user's task before writing code. Ask (max 1 question):
- •What is the user trying to accomplish? (not "what entity to CRUD")
- •What is the primary action on this screen?
If the request is clear enough, skip questions and propose the approach inline before coding.
Decision Flow
- •Receive request → Identify screen type (form, list, dashboard, detail, wizard)
- •Read the relevant reference file:
- •UX principles, accessibility, visual hierarchy → references/UX.md
- •Screen patterns: forms, lists, wizards, dashboards, offline → references/PATTERNS.md
- •Reusable components, hooks, code recipes → references/COMPONENTS.md
- •Implement following stack conventions below
- •Question bad requests → "You asked for X, but that may cause [problem]. Consider [alternative]?"
Stack & Conventions
Dependencies: Vite, React 18+, Mantine v7+ (@mantine/core, @mantine/hooks, @mantine/modals, @mantine/notifications), React Hook Form + @hookform/resolvers + Zod, TanStack Query v5, React Router v6, @tabler/icons-react.
File structure:
code
src/ ├── components/ │ ├── common/ # Reusable: Form/, Layout/, Feedback/, Data/ │ └── features/[name]/ # Domain-specific components ├── hooks/ # Custom hooks ├── pages/ # Route-level views ├── services/ # API layer (fetch/axios wrappers) ├── schemas/ # Zod schemas (source of truth for types) ├── types/ # TypeScript types not derived from Zod ├── utils/ # Pure helpers └── styles/ # Mantine theme overrides
Code rules:
- •Zod schema first → derive types with
z.infer<> - •
mode: 'onChange'on forms for real-time validation - •Disable submit until
isValid && isDirty - •Every async action needs loading state
- •Destructive actions require confirmation via
@mantine/modals - •TanStack Query for all server state; invalidate queries after mutations
- •Empty states mandatory: "no data" vs "no search results"
- •Error states mandatory: specific messages + retry action
Quick Imports
tsx
// Forms
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
// Mantine
import { TextInput, Button, Stack, Group, Table, Loader, Center } from '@mantine/core';
import { useDebouncedValue } from '@mantine/hooks';
import { modals } from '@mantine/modals';
import { notifications } from '@mantine/notifications';
// Data
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
// Icons
import { IconPlus, IconEdit, IconTrash, IconSearch } from '@tabler/icons-react';
Testing
When tests are requested or project includes test setup:
- •@testing-library/react + vitest for components
- •MSW for API mocking
- •vitest-axe for accessibility
- •Test user interactions, not implementation details