react-admin-migo
v1.0.3
Published
A CLI tool to bootstrap React Admin Framework projects
Maintainers
Readme
React Admin Migo 🚀
A comprehensive CLI tool to generate production-ready React Admin Dashboards with built-in dynamic forms and Arabic i18n support.
Badges
These shields are used for the project status:
https://img.shields.io/npm/v/react-admin-migo.svghttps://img.shields.io/npm/l/react-admin-migo.svghttps://img.shields.io/badge/TypeScript-5.7-bluehttps://img.shields.io/badge/Arabic-RTL-green
✨ Why React Admin Migo?
🚀 From Zero to Admin Panel in Minutes
Create fully-functional admin dashboards with dynamic forms, authentication, and multi-language support using just two files.
🌍 Built-in Arabic RTL Support
Fully configured Arabic i18n with RTL layout, animations, and date formatting ready from day one.
📦 Features
Complete Stack Pre-Configured
- ⚛️ React 19 with TypeScript
- 🎨 Material-UI (MUI) with Emotion styling
- 🔄 Redux Toolkit for state management
- 🧭 React Router v7 with nested routes
- 🌐 i18n with Arabic/English support (RTL/LTR ready)
- 🎯 Tailwind CSS for utility classes
- 📏 ESLint + Prettier pre-configured
- ⚡ Vite for fast builds and HMR
🔥 Dynamic Form System (The Game-Changer)
Create complex, validated forms with only two files:
Language: bash
📁 validations/create{{FormName}}.ts # Validation schema (Zod)
📁 pages/create{{PageName}}.tsx # Complete form pageSupports file uploads with is_formData={true} for photo upload fields!
🚀 Quick Start
Language: bash
# Using full name
npx react-admin-migo my-project
# Or using the short alias
npx migo my-projectThen:
Language: bash
cd my-project
npm run dev📋 Dynamic Form Example: Create User Form
1. Validation Schema (validations/createUserSchema.ts)
Language: 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<typeof formDataSchema>;2. Form Page (pages/CreateUserPage.tsx)
Language: 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: "[email protected]",
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 (
<div>
<PageTitle title={t("users.addUser")} className={"underline"} />
<DynamicForm
gridSize={gridSize}
defaultValues={defaultValues}
formInputs={userFormInputs}
formDataSchema={formDataSchema}
endpoints={CREATE_USER}
actionBtn={t("create")}
is_formData={true} // Enable file upload with FormData
/>
</div>
);
}
export default CreateUserPage;3. Form Inputs Configuration (components/users/userFormInputs.ts)
Language: 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: <PersonIcon />, type: "text" },
{
name: "name_ar",
label: "الاسم بالعربية",
icon: <TranslateIcon />,
type: "text",
},
{
name: "email",
label: "Email",
icon: <AlternateEmailIcon />,
type: "email",
},
{
name: "mobile_number",
label: "Mobile Number",
icon: <PhoneIphoneIcon />,
type: "tel",
},
{
name: "identification",
label: "Identification",
icon: <BadgeIcon />,
type: "text",
},
{
name: "birthdate",
label: "Birthdate",
type: "date_calendar",
icon: <CalendarMonthIcon />,
minDate: dayjs("1900-01-01"),
maxDate: dayjs(),
},
{
name: "password",
label: "Password",
type: "password",
icon: <VpnKeyIcon />,
},
{
name: "confirm_password",
label: "Confirm Password",
type: "password",
icon: <VpnKeyIcon />,
},
{
name: "gender",
label: "Gender",
icon: <Man4Icon />,
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: <GroupsIcon />,
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: <PersonIcon />, type: "text" },
{
name: "education",
label: "Education",
icon: <SchoolIcon />,
type: "text",
},
{
name: "home_address",
label: "Home Address",
type: "textarea",
icon: <HomeIcon />,
},
{
name: "photo",
label: "Profile Photo",
type: "upload_photo",
icon: <PersonIcon />,
multiple: false,
variant: "circular",
previewSize: { width: 200, height: 200 },
// Only works when is_formData={true}
},
{
name: "cover",
label: "Cover Photo",
type: "upload_photo",
icon: <PersonIcon />,
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 [email protected] 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 | [email protected] | 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
<DynamicForm
// ... other props
is_formData={true} // Enable FormData for file uploads
/>File Upload Configuration:
Language: typescript
{
name: 'photo',
label: 'Profile Photo',
type: 'upload_photo',
icon: <PersonIcon />,
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
// 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
<motion.div variants={itemVariants} initial="hidden" animate="visible">
<Typography>{t("welcome.message")}</Typography>
</motion.div>;📁 Project Structure
Language: 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
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.tsxinput mapping - Use in your form configurations
Enabling File Uploads for Forms
- Set
is_formData={true}onDynamicForm - Add
upload_photofields to your form inputs - Ensure backend accepts
FormDatawith files
🤝 Contributing
We welcome contributions! Please:
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
📄 License
MIT © [Magdy Zahran]. See the LICENSE file for details.
🙏 Acknowledgments
- Material-UI team for the amazing component library
- Vite team for the incredible build tool
- i18next for internationalization solutions
- The Arabic developer community for inspiration
⚡ Stop building admin panels from scratch. Start with React Admin Migo.
🌍 Perfect for Arabic-speaking developers and international teams.
Built with ❤️ for the React community
