Model.Template.tsx Implementation Guide

Model.Template.tsx files are client-side React components that define the form structure for creating/editing models in Akan.js applications. They serve as reusable form blueprints with built-in state management, validation, and internationalization support.
File Location and Naming Convention
Template files follow a consistent naming pattern and directory structure:
// Standard path pattern
{apps,libs}/*/lib/[model]/[Model].Template.tsx
// Examples:
libs/game/lib/map/Map.Template.tsx
apps/lu/lib/feeling/Feeling.Template.tsx
        
Basic Structure and Component Patterns
Component Organization
// Single-file pattern
export const General = () => { /* main form */ }
export const Advanced = () => { /* advanced fields */ }
// Multi-file pattern (recommended)
[Model].Template/
├─ General.tsx
├─ Sections/
│  ├─ BasicInfo.tsx
│  ├─ ContactDetails.tsx
        
State Initialization
useEffect(() => {
  if (id) {
    // Load existing data
    void st.do.load[Model](id);
  }
  
  return () => {
    // Reset form on unmount
    st.do.reset[Model]Form();
  };
}, [id]);
        
Field Types and Form Components
Text

Standard text input field

<Field.Text />
TextArea

Multi-line text input

<Field.TextArea />
Select

Dropdown selection input

<Field.Select />
ToggleSelect

Toggleable options selector

<Field.ToggleSelect />
Img

Image upload component

<Field.Img sliceName='model' />
Parent

Relationship selector

<Field.Parent sliceName='relatedModel' />
Complex Field Example
<Field.List
  label={l.field("map", "spawnPositions")}
  value={form.spawnPositions}
  onAdd={() => st.do.addSpawnPosition(defaultPosition)}
  renderItem={(position, idx) => (
    <div className="flex gap-4">
      <Field.Text
        value={position.key}
        onChange={(v) => st.do.writeOnMap(["spawnPositions", idx, "key"], v)}
      />
      <Field.DoubleNumber
        value={position.position}
        onChange={(v) => st.do.writeOnMap(["spawnPositions", idx, "position"], v)}
      />
    </div>
  )}
/>
        
Form Validation Approaches
Field-Level Validation
<Field.Email
  value={form.email}
  validate={(v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)}
  errorMessage="Invalid email format"
  required
/>
        
required:boolean:false

Makes field mandatory

required
min/max:number:-

Number range constraints

min={0} max={100}
validate:function:-

Custom validation function

validate={(v) => isValidEmail(v)}
errorMessage:string:-

Custom error message

errorMessage="Invalid format"
Form Layout Patterns
Responsive Grid Layout
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
  <Field.Text label="First Name" />
  <Field.Text label="Last Name" />
  <Field.Email label="Email" className="md:col-span-2" />
</div>
        
Conditional Sections
{form.type === "business" && (
  <section className="mt-6 p-4 bg-base-200 rounded-lg">
    <h3 className="text-lg font-semibold mb-3">Business Details</h3>
    <Field.Text label="Company Name" />
    <Field.Text label="Tax ID" />
  </section>
)}
        
State Management
Store Action Patterns
// Simple field update
st.do.setNameOn[Model](value);
// Nested field update
st.do.writeOn[Model](["address", "city"], value);
// List operations
st.do.addItemOn[Model](newItem);
st.do.removeItemOn[Model](index);
        
Performance Optimization
Memoization Techniques
const FormSection = React.memo(({ fields }) => {
  // Component implementation
});
// Debounced inputs
import { useDebounce } from "@akanjs/hooks";
const [input, setInput] = useState("");
const debouncedInput = useDebounce(input, 300);
        
Accessibility
Accessible Form Patterns
// Proper labeling
<label htmlFor="email-field">Email</label>
<input id="email-field" type="email" />
// Error messaging
<div role="alert" aria-live="polite">
  {error && <p className="text-error">{error}</p>}
</div>
        
Common Patterns
Reusable Form Sections
// AddressSection.tsx
export const AddressSection = () => (
  <div className="space-y-3">
    <Field.Text label="Street" />
    <Field.Text label="City" />
    <Field.Text label="Zip Code" />
  </div>
);
        
Form Submission
Submission Workflow
const handleSubmit = async () => {
  try {
    // Validate form
    const errors = validateForm(form);
    if (Object.keys(errors).length) throw errors;
    
    // Submit data
    if (id) await st.do.updateModel(id, form);
    else await st.do.createModel(form);
    
    // Redirect on success
    router.push("/success");
  } catch (error) {
    // Handle API errors
    st.do.setFormErrors(error);
  }
};
        
Troubleshooting
Form Not Updating

Verify Zustand store actions are properly connected

st.do.setNameOn[Model]
Type Mismatches

Ensure constant types match form state

ProjectInput vs ProjectForm
Missing Translations

Verify dictionary keys and scopes

l.field("model", "name")
Best Practices
1. Use consistent spacing (gap-4, mb-4) 2. Group related fields visually 3. Place important fields above the fold 4. Provide clear validation feedback 5. Meet WCAG 2.1 accessibility standards
Released under the MIT License
Official Akan.js Consulting onAkansoft
Copyright © 2025 Akan.js. All rights reserved.
System managed bybassman