A CLI tool to bootstrap React Admin Framework projects
npm install react-admin-migohttps://img.shields.io/npm/v/react-admin-migo.svg
https://img.shields.io/npm/l/react-admin-migo.svg
https://img.shields.io/badge/TypeScript-5.7-blue
https://img.shields.io/badge/Arabic-RTL-green
bash
bash
š validations/create{{FormName}}.ts # Validation schema (Zod)
š pages/create{{PageName}}.tsx # Complete form page
`
Supports file uploads with is_formData={true} for photo upload fields!
---
š Quick Start
Language: bash
`bash
Using full name
npx react-admin-migo my-project
Or using the short alias
npx migo my-project
`
Then:
Language: bash
`bash
cd my-project
npm run dev
`
---
š Dynamic Form Example: Create User Form
$3
Language: typescript
`typescript
import { z } from "zod";
export const formDataSchema = z
.object({
name: z.string().min(2, "Name must be at least 2 characters"),
name_ar: z.string().min(2, "Ų§ŁŲ§Ų³Ł
ŲØŲ§ŁŲ¹Ų±ŲØŁŲ© ŁŲ¬ŲØ Ų£Ł ŁŁŁŁ Ų¹ŁŁ Ų§ŁŲ£ŁŁ ŲŲ±ŁŁŁ"),
email: z.string().email("Invalid email address"),
password: z.string().min(8, "Password must be at least 8 characters"),
confirm_password: z.string(),
identification: z
.string()
.length(15, "Identification must be 15 characters"),
birthdate: z.string().optional(),
gender: z.enum(["male", "female", ""]).optional(),
groups: z.array(z.string()).optional(),
is_active: z.boolean().default(true),
photo: z.any().optional(), // For file upload
cover: z.any().optional(), // For file upload
})
.refine((data) => data.password === data.confirm_password, {
message: "Passwords don't match",
path: ["confirm_password"],
});
export type TFormData = z.infer;
`
$3
Language: typescript
`typescript
import DynamicForm from "@/components/form/DynamicForm";
import PageTitle from "@/components/global/PageTitle";
import { useTranslation } from "react-i18next";
import { getGridSize } from "@/components/form/FormRows";
import { userFormInputs } from "@/components/users/userFormInputs";
import { formDataSchema, TFormData } from "@/validations/createUserSchema";
import { CREATE_USER } from "@/utils/endpoints";
function CreateUserPage() {
const defaultValues: TFormData = {
name: "User 1",
name_ar: "Ł
Ų³ŲŖŲ®ŲÆŁ
1",
email: "user@example.com",
password: "Testpass123",
confirm_password: "Testpass123",
identification: "012345678912345",
birthdate: "1986-03-01",
gender: "",
groups: ["normal"],
is_active: true,
// photo: undefined, // Files will be uploaded separately
// cover: undefined,
};
const { t } = useTranslation();
const gridSize = getGridSize(6, 6, 12);
return (
gridSize={gridSize}
defaultValues={defaultValues}
formInputs={userFormInputs}
formDataSchema={formDataSchema}
endpoints={CREATE_USER}
actionBtn={t("create")}
is_formData={true} // Enable file upload with FormData
/>
);
}
export default CreateUserPage;
`
$3
Language: typescript
`typescript
import PersonIcon from "@mui/icons-material/Person";
import VpnKeyIcon from "@mui/icons-material/VpnKey";
import TranslateIcon from "@mui/icons-material/Translate";
import AlternateEmailIcon from "@mui/icons-material/AlternateEmail";
import PhoneIphoneIcon from "@mui/icons-material/PhoneIphone";
import BadgeIcon from "@mui/icons-material/Badge";
import CalendarMonthIcon from "@mui/icons-material/CalendarMonth";
import Man4Icon from "@mui/icons-material/Man4";
import HomeIcon from "@mui/icons-material/Home";
import SchoolIcon from "@mui/icons-material/School";
import GroupsIcon from "@mui/icons-material/Groups";
import dayjs from "dayjs";
export const userFormInputs = [
[
{
name: "is_active",
label: "Active Account",
type: "switch",
defaultChecked: true,
gridSize: { xs: 12, sm: 12, md: 12 },
},
{ name: "**section_required", type: "section", label: "Required" },
{ name: "name", label: "Name", icon: , type: "text" },
{
name: "name_ar",
label: "Ų§ŁŲ§Ų³Ł
ŲØŲ§ŁŲ¹Ų±ŲØŁŲ©",
icon: ,
type: "text",
},
{
name: "email",
label: "Email",
icon: ,
type: "email",
},
{
name: "mobile_number",
label: "Mobile Number",
icon: ,
type: "tel",
},
{
name: "identification",
label: "Identification",
icon: ,
type: "text",
},
{
name: "birthdate",
label: "Birthdate",
type: "date_calendar",
icon: ,
minDate: dayjs("1900-01-01"),
maxDate: dayjs(),
},
{
name: "password",
label: "Password",
type: "password",
icon: ,
},
{
name: "confirm_password",
label: "Confirm Password",
type: "password",
icon: ,
},
{
name: "gender",
label: "Gender",
icon: ,
type: "select",
options: [
{ label: "Select gender", value: "" },
{ label: "Male", value: "male" },
{ label: "Female", value: "female" },
],
gridSize: { xs: 12, sm: 6, md: 6 },
},
{
name: "groups",
label: "Groups",
icon: ,
type: "multi_select",
options: [
{ id: "admins", name: "Admins" },
{ id: "normal", name: "Normal" },
],
gridSize: { xs: 12, sm: 6, md: 6 },
},
{ name: "**section_optional", type: "section", label: "Optional" },
{ name: "position", label: "Position", icon: , type: "text" },
{
name: "education",
label: "Education",
icon: ,
type: "text",
},
{
name: "home_address",
label: "Home Address",
type: "textarea",
icon: ,
},
{
name: "photo",
label: "Profile Photo",
type: "upload_photo",
icon: ,
multiple: false,
variant: "circular",
previewSize: { width: 200, height: 200 },
// Only works when is_formData={true}
},
{
name: "cover",
label: "Cover Photo",
type: "upload_photo",
icon: ,
multiple: false,
variant: "square",
previewSize: { width: 320, height: 200 },
// Only works when is_formData={true}
},
],
];
`
---
šØ Supported Field Types
Original raw description:
> Type Description Example Use Notes
> text Text input Username, Name Basic text field
> email Email input user@example.com Email validation
> password Password field Secret password Masked input
> select Dropdown selection Gender, Country Single choice
> multi_select Multiple selection User groups, Tags Multiple choices
> switch Toggle switch Active status Boolean field
> date_calendar Date picker Birthdate, Due date Date selection
> textarea Multi-line text Address, Description Long text input
> upload_photo Image upload Profile picture Requires is_formData={true}
> section Form section header Grouping fields Visual separator
Formatted as a table:
| Type | Description | Example Use | Notes |
| --------------- | ------------------- | -------------------- | ----------------------------- |
| text | Text input | Username, Name | Basic text field |
| email | Email input | user@example.com | Email validation |
| password | Password field | Secret password | Masked input |
| select | Dropdown selection | Gender, Country | Single choice |
| multi_select | Multiple selection | User groups, Tags | Multiple choices |
| switch | Toggle switch | Active status | Boolean field |
| date_calendar | Date picker | Birthdate, Due date | Date selection |
| textarea | Multi-line text | Address, Description | Long text input |
| upload_photo | Image upload | Profile picture | Requires is_formData={true} |
| section | Form section header | Grouping fields | Visual separator |
---
ā” File Upload Feature
How to Enable File Uploads:
Language: typescript
`typescript
// ... other props
is_formData={true} // Enable FormData for file uploads
/>
`
File Upload Configuration:
Language: typescript
`typescript
{
name: 'photo',
label: 'Profile Photo',
type: 'upload_photo',
icon: ,
multiple: false, // Single file upload
variant: 'circular', // 'circular' or 'square'
previewSize: { width: 200, height: 200 }, // Preview dimensions
}
`
---
š Built-in Arabic i18n & RTL Support
Complete RTL Experience
- Automatic layout flipping for Arabic (RTL) and English (LTR)
- Framer Motion animations that respect direction
- MUI components fully RTL compatible
- Date formatting in both Hijri and Gregorian
- Arabic calendar with proper month names
Language Switching Example
Language: typescript
`typescript
// Navigation with RTL-aware animations
const itemVariants = {
hidden: language === "ar" ? { x: 50, opacity: 0 } : { x: -50, opacity: 0 },
visible: {
x: 0,
opacity: 1,
transition: {
type: "spring",
stiffness: 50,
damping: 25,
},
},
};
// Usage in components
{t("welcome.message")}
;
`
---
š Project Structure
Language: text
`text
my-admin-project/
āāā src/
ā āāā components/
ā ā āāā form/ # Dynamic form components
ā ā ā āāā DynamicForm.tsx
ā ā ā āāā FormRows.tsx
ā ā ā āāā FormInputs/ # Custom form inputs
ā ā āāā global/ # Reusable components
ā ā āāā layout/ # Layout components
ā āāā pages/ # Application pages
ā āāā validations/ # Zod validation schemas
ā āāā store/ # Redux store & slices
ā āāā utils/ # Utilities & helpers
ā āāā locales/ # i18n translation files
ā ā āāā ar/ # Arabic translations (RTL)
ā ā ā āāā common.json
ā ā ā āāā users.json
ā ā ā āāā forms.json
ā ā āāā en/ # English translations (LTR)
ā āāā types/ # TypeScript definitions
āāā public/
ā āāā locales/ # Public translation files
ā āāā images/
āāā index.html
āāā package.json
`
---
š§ Available Scripts
Language: bash
`bash
npm run dev # Start development server (http://localhost:5173)
npm run build # Build for production
npm run preview # Preview production build
npm run lint # Lint and fix code
npm run type-check # TypeScript type checking
npm run i18n # Extract translation keys
`
---
š¦ Dependencies Included
Core
- React 19 + React DOM
- TypeScript 5.7
- Vite 6.x
UI & Styling
- Material-UI (MUI) with icons
- Emotion (CSS-in-JS)
- Tailwind CSS
- Framer Motion (Animations)
State & Routing
- Redux Toolkit
- React Router 7
- React Hook Form
- Zod (Validation)
Internationalization
- i18next (with Arabic/English bundles)
- react-i18next
- i18next-browser-languagedetector
HTTP & Utilities
- Axios (HTTP client)
- Day.js (Date handling with Arabic support)
---
š Customization
Adding New Languages
- Add translation files in src/locales/{langCode}/
- Update i18n configuration in src/i18n.ts
- Add language selector in your layout
- Update RTL settings if needed
Creating Custom Form Inputs
- Create component in src/components/form/FormInputs/
- Register in DynamicForm.tsx input mapping
- Use in your form configurations
Enabling File Uploads for Forms
- Set is_formData={true} on DynamicForm
- Add upload_photo fields to your form inputs
- Ensure backend accepts FormData` with files