@@ -268,6 +268,157 @@ const { mutate } = useMutation<Task, Partial<Task>>('todo_task', 'create');
268268// mutate expects Partial<Task>
269269```
270270
271+ ## Common Patterns
272+
273+ ### Master-Detail View
274+
275+ ``` tsx
276+ function TaskList() {
277+ const [selectedId, setSelectedId] = useState <string | null >(null );
278+
279+ const { data : tasks } = useQuery (' todo_task' , {
280+ select: [' id' , ' subject' ],
281+ sort: [' -created_at' ]
282+ });
283+
284+ const { data : selectedTask } = useQuery (' todo_task' , {
285+ filters: [' id' , ' =' , selectedId ],
286+ enabled: !! selectedId // Only fetch when ID is selected
287+ });
288+
289+ return (
290+ <div className = " flex" >
291+ <TaskListPanel tasks = { tasks ?.value } onSelect = { setSelectedId } />
292+ <TaskDetail task = { selectedTask ?.value ?.[0 ]} />
293+ </div >
294+ );
295+ }
296+ ```
297+
298+ ### Optimistic Updates
299+
300+ ``` tsx
301+ function TaskToggle({ taskId , completed }) {
302+ const { mutate } = useMutation (' todo_task' , ' update' , {
303+ onMutate : async (variables ) => {
304+ // Optimistically update UI
305+ return { previousValue: completed };
306+ },
307+ onError : (error , variables , context ) => {
308+ // Revert on error
309+ console .error (' Update failed, reverting' , context .previousValue );
310+ },
311+ onSuccess : () => {
312+ // Refetch to ensure data consistency
313+ queryClient .invalidateQueries ([' todo_task' ]);
314+ }
315+ });
316+
317+ return (
318+ <Checkbox
319+ checked = { completed }
320+ onChange = { (e ) => mutate ({ id: taskId , is_completed: e .target .checked })}
321+ />
322+ );
323+ }
324+ ```
325+
326+ ### Dependent Queries
327+
328+ ``` tsx
329+ function ProjectTasks({ projectId }) {
330+ // First, get project details
331+ const { data : project } = useQuery (' project' , {
332+ filters: [' id' , ' =' , projectId ]
333+ });
334+
335+ // Then, get tasks for this project
336+ const { data : tasks } = useQuery (' todo_task' , {
337+ filters: [' project_id' , ' =' , projectId ],
338+ enabled: !! project // Only fetch when project is loaded
339+ });
340+
341+ return (
342+ <div >
343+ <h2 >{ project ?.value ?.[0 ]?.name } </h2 >
344+ <TaskList tasks = { tasks ?.value } />
345+ </div >
346+ );
347+ }
348+ ```
349+
350+ ### Search with Debounce
351+
352+ ``` tsx
353+ import { useDeferredValue } from ' react' ;
354+
355+ function TaskSearch() {
356+ const [searchTerm, setSearchTerm] = useState (' ' );
357+ const deferredSearch = useDeferredValue (searchTerm );
358+
359+ const { data, isLoading } = useQuery (' todo_task' , {
360+ filters: [' subject' , ' contains' , deferredSearch ],
361+ enabled: deferredSearch .length >= 3 // Only search with 3+ chars
362+ });
363+
364+ return (
365+ <div >
366+ <input
367+ type = " text"
368+ value = { searchTerm }
369+ onChange = { (e ) => setSearchTerm (e .target .value )}
370+ placeholder = " Search tasks..."
371+ />
372+ { isLoading && <Spinner />}
373+ <TaskList tasks = { data ?.value } />
374+ </div >
375+ );
376+ }
377+ ```
378+
379+ ### Form with Validation
380+
381+ ``` tsx
382+ function TaskForm() {
383+ const { mutate, isLoading, error } = useMutation (' todo_task' , ' create' , {
384+ onSuccess : () => {
385+ router .push (' /tasks' );
386+ }
387+ });
388+
389+ const handleSubmit = (e : FormEvent <HTMLFormElement >) => {
390+ e .preventDefault ();
391+ const formData = new FormData (e .currentTarget );
392+
393+ mutate ({
394+ subject: formData .get (' subject' ),
395+ priority: Number (formData .get (' priority' )),
396+ due_date: formData .get (' due_date' )
397+ });
398+ };
399+
400+ return (
401+ <form onSubmit = { handleSubmit } >
402+ <input name = " subject" required />
403+ <input name = " priority" type = " number" min = " 1" max = " 5" />
404+ <input name = " due_date" type = " date" />
405+
406+ { error && (
407+ <div className = " error" >
408+ { error .code === ' validation_error'
409+ ? ' Please check your input'
410+ : error .message }
411+ </div >
412+ )}
413+
414+ <button type = " submit" disabled = { isLoading } >
415+ { isLoading ? ' Creating...' : ' Create Task' }
416+ </button >
417+ </form >
418+ );
419+ }
420+ ```
421+
271422## License
272423
273424Apache-2.0
0 commit comments