Ignitech Frontend Modules Library - Reusable components for Ignitech websites
npm install @ignitech/modulesbash
npm install @ignitech/modules
hoặc
yarn add @ignitech/modules
`
Import Modules
$3
`tsx
import { ContactForm, PaymentMethod } from '@ignitech/modules';
`
$3
`tsx
// Chỉ import Contact Form module
import { ContactForm, useContactForm } from '@ignitech/modules/contact';
// Chỉ import Payment module
import { PaymentMethod, usePayment } from '@ignitech/modules/payment';
// Chỉ import utilities
import { apiFetch, getApiBaseUrl } from '@ignitech/modules/utils';
`
Lợi ích của import riêng lẻ:
- Bundle size nhỏ hơn (chỉ bundle code cần thiết)
- Tree-shaking tốt hơn
- Load time nhanh hơn
- Phù hợp khi website chỉ cần 1-2 module
Modules
$3
Module xử lý form liên hệ với validation và gửi dữ liệu đến API backend.
#### Sử dụng Component
`tsx
// Cách 1: Import từ subpath (khuyến nghị)
import { ContactForm } from '@ignitech/modules/contact';
// Cách 2: Import từ main entry
import { ContactForm } from '@ignitech/modules';
function App() {
return (
title="Liên hệ với chúng tôi"
description="Điền thông tin để chúng tôi có thể liên hệ lại"
apiBaseUrl="https://api.example.com"
onSuccess={(data) => console.log('Success:', data)}
onError={(error) => console.error('Error:', error)}
/>
);
}
`
#### Sử dụng Hook
`tsx
// Cách 1: Import từ subpath (khuyến nghị)
import { useContactForm } from '@ignitech/modules/contact';
// Cách 2: Import từ main entry
import { useContactForm } from '@ignitech/modules';
function CustomContactForm() {
const { submit, isLoading, error, success } = useContactForm({
apiBaseUrl: 'https://api.example.com',
onSuccess: (data) => console.log('Success:', data),
});
const handleSubmit = async () => {
await submit({
name: 'Nguyễn Văn A',
phone: '0912345678',
email: 'example@email.com',
content: 'Nội dung tin nhắn',
});
};
return (
{/ Your custom form UI /}
{error && {error}
}
{success && Gửi thành công!
}
);
}
`
#### Props
| Prop | Type | Default | Mô tả |
|------|------|---------|-------|
| title | string | "Liên hệ với chúng tôi" | Tiêu đề form |
| description | string | - | Mô tả form |
| submitButtonText | string | "Gửi tin nhắn" | Text nút submit |
| apiBaseUrl | string | - | URL base của API backend |
| onSuccess | (data: ContactFormData) => void | - | Callback khi gửi thành công |
| onError | (error: string) => void | - | Callback khi có lỗi |
| showLabels | boolean | true | Hiển thị labels cho các input |
| placeholder | object | - | Custom placeholder cho các field |
| className | string | - | CSS class tùy chỉnh |
Xem hướng dẫn chi tiết: Contact Module README
$3
Module xử lý tạo đơn hàng và chuyển hướng đến cổng thanh toán.
#### Sử dụng Component
`tsx
// Cách 1: Import từ subpath (khuyến nghị)
import { PaymentMethod } from '@ignitech/modules/payment';
// Cách 2: Import từ main entry
import { PaymentMethod } from '@ignitech/modules';
function App() {
return (
title="Thanh toán đơn hàng"
amount={100000}
availableMethods={['momo', 'zalopay', 'vnpay']}
apiBaseUrl="https://api.example.com"
onSuccess={(orderId) => console.log('Order created:', orderId)}
autoRedirect={true}
/>
);
}
`
#### Sử dụng Hook
`tsx
// Cách 1: Import từ subpath (khuyến nghị)
import { usePayment } from '@ignitech/modules/payment';
// Cách 2: Import từ main entry
import { usePayment } from '@ignitech/modules';
function CustomPayment() {
const { createOrder, isLoading, error, orderData } = usePayment({
apiBaseUrl: 'https://api.example.com',
autoRedirect: true,
});
const handlePayment = async () => {
await createOrder({
amount: 100000,
method: 'momo',
});
};
return (
{/ Your custom payment UI /}
{error && {error}
}
);
}
`
#### Props
| Prop | Type | Default | Mô tả |
|------|------|---------|-------|
| title | string | "Thanh toán" | Tiêu đề form |
| description | string | - | Mô tả form |
| amount | number | - | Số tiền thanh toán |
| defaultMethod | PaymentMethod | "momo" | Phương thức thanh toán mặc định |
| availableMethods | PaymentMethod[] | ['momo', 'zalopay', 'vnpay'] | Danh sách phương thức thanh toán |
| submitButtonText | string | "Thanh toán" | Text nút submit |
| apiBaseUrl | string | - | URL base của API backend |
| onSuccess | (orderId: string) => void | - | Callback khi tạo đơn thành công |
| onError | (error: string) => void | - | Callback khi có lỗi |
| autoRedirect | boolean | true | Tự động chuyển hướng đến cổng thanh toán |
| showAmountInput | boolean | false | Hiển thị input để nhập số tiền |
| className | string | - | CSS class tùy chỉnh |
Xem hướng dẫn chi tiết: Payment Module README
$3
Module xử lý SEO (Search Engine Optimization) cho website, bao gồm meta tags, structured data, và social media tags.
#### Sử dụng Component
`tsx
// Cách 1: Import từ subpath (khuyến nghị)
import { MetaTags, useSEO, StructuredData } from '@ignitech/modules/seo';
// Cách 2: Import từ main entry
import { MetaTags, useSEO } from '@ignitech/modules';
function ContactPage() {
const { seoData } = useSEO({
title: 'Liên hệ với chúng tôi',
description: 'Điền form để liên hệ với chúng tôi',
keywords: ['liên hệ', 'contact'],
siteName: 'Tên Website',
siteUrl: 'https://example.com',
});
return (
<>
type="ContactPage"
data={{
name: 'Tên công ty',
url: 'https://example.com/contact',
}}
/>
{/ Your page content /}
>
);
}
`
#### Sử dụng Hook
`tsx
import { useSEO } from '@ignitech/modules/seo';
function Page() {
const {
seoData,
fullTitle,
validation,
} = useSEO({
title: 'Page Title',
description: 'Page description',
siteName: 'Site Name',
});
// Use seoData to update document head
useEffect(() => {
if (seoData.title) {
document.title = seoData.title;
}
}, [seoData]);
return {/ Your content /};
}
`
#### Props
| Prop | Type | Default | Mô tả |
|------|------|---------|-------|
| title | string | - | Tiêu đề trang |
| description | string | - | Mô tả trang |
| keywords | string \| string[] | - | Keywords |
| siteName | string | - | Tên website |
| siteUrl | string | - | URL website |
| ogImage | string | - | Open Graph image |
| canonical | string | - | Canonical URL |
Xem hướng dẫn chi tiết: SEO Module README
Kiến trúc
Mỗi module được tổ chức theo 3 lớp:
1. Service Layer - Xử lý API communication
2. Hook Layer - Quản lý state và logic
3. Component Layer - UI components
`
src/
contact/
ContactForm.tsx # Component
useContactForm.ts # Hook
contact.service.ts # Service
index.ts
payment/
PaymentMethod.tsx # Component
usePayment.ts # Hook
payment.service.ts # Service
index.ts
seo/
components/ # SEO Components
hooks/ # SEO Hooks
utils/ # SEO Utilities
index.ts
utils/
types.ts
fetch.ts
validators.ts
`
Cấu hình API
Module tự động lấy API base URL theo thứ tự ưu tiên:
1. Prop apiBaseUrl (nếu được truyền vào)
2. window.IGNITECH_API_BASE_URL (global variable)
3. process.env.REACT_APP_API_BASE_URL hoặc process.env.NEXT_PUBLIC_API_BASE_URL
$3
`tsx
// Option 1: Truyền qua props
// Option 2: Set global variable
window.IGNITECH_API_BASE_URL = 'https://api.example.com';
// Option 3: Environment variable
// .env
REACT_APP_API_BASE_URL=https://api.example.com
`
API Endpoints
$3
- POST /api/contact - Gửi form liên hệ
Request body:
`json
{
"name": "Nguyễn Văn A",
"phone": "0912345678",
"email": "example@email.com",
"content": "Nội dung tin nhắn"
}
`
$3
- POST /api/payment/orders - Tạo đơn hàng
Request body:
`json
{
"amount": 100000,
"method": "momo",
"description": "Mô tả đơn hàng"
}
`
Response:
`json
{
"success": true,
"data": {
"orderId": "order_123",
"paymentUrl": "https://payment-gateway.com/...",
"qrCode": "data:image/png;base64,...",
"amount": 100000,
"method": "momo",
"status": "pending"
}
}
`
- GET /api/payment/orders/:orderId/status - Kiểm tra trạng thái thanh toán
Styling
Components sử dụng CSS Variables (CSS Custom Properties) để cho phép website tùy biến hoàn toàn màu sắc, font chữ và styling.
$3
Tạo file CSS để override CSS variables:
`css
/ styles/ignitech-theme.css /
:root {
/ Brand colors /
--ignitech-primary: #ff6b6b;
--ignitech-primary-hover: #ee5a5a;
--ignitech-error: #c92a2a;
--ignitech-success: #51cf66;
/ Typography /
--ignitech-font-family: 'Inter', sans-serif;
--ignitech-font-size-base: 1rem;
/ Spacing & Border /
--ignitech-border-radius: 0.5rem;
}
`
Import vào website:
`tsx
// Next.js
import './styles/ignitech-theme.css';
// Hoặc import CSS variables mặc định (optional)
import '@ignitech/modules/styles/variables.css';
`
Xem hướng dẫn chi tiết: STYLING.md
$3
Bạn cũng có thể thêm custom CSS classes:
`tsx
className="max-w-md mx-auto p-6 bg-white rounded-lg shadow-lg"
/>
`
Tích hợp vào Website
Xem hướng dẫn tích hợp: INTEGRATION.md
Next.js Support
Modules hoàn toàn tương thích với Next.js (cả Pages Router và App Router).
Xem hướng dẫn chi tiết: NEXTJS.md
$3
`tsx
// app/contact/page.tsx
'use client';
import { ContactForm } from '@ignitech/modules/contact';
export default function ContactPage() {
return (
apiBaseUrl={process.env.NEXT_PUBLIC_API_BASE_URL}
onSuccess={(data) => console.log('Success:', data)}
/>
);
}
`
Validation
Module sử dụng Zod để validate dữ liệu:
- Email: Format email hợp lệ
- Phone: 10-11 chữ số hoặc format +84
- Name: 2-100 ký tự
- Content: 10-1000 ký tự
- Amount: Số dương
Build
`bash
npm run build
`
Output sẽ được tạo trong thư mục dist/ với:
- CommonJS (dist/index.js)
- ES Modules (dist/index.esm.js)
- TypeScript definitions (dist/index.d.ts)
Development
`bash
npm run dev # Watch mode
npm run type-check # Type checking
npm run lint # Linting
`
License
MIT
Đóng góp
Module này được thiết kế để dễ dàng mở rộng. Khi thêm module mới:
1. Tạo thư mục module trong src/
2. Tổ chức theo cấu trúc: Service → Hook → Component
3. Export từ src/index.ts
4. Cập nhật README
Best Practices
$3
Nên dùng subpath import khi:
- Website chỉ sử dụng 1-2 module
- Muốn tối ưu bundle size
- Quan tâm đến performance
`tsx
// Tốt - chỉ bundle Contact module
import { ContactForm } from '@ignitech/modules/contact';
`
Có thể dùng main import khi:
- Website sử dụng nhiều module (3+)
- Không quan tâm bundle size
- Muốn code ngắn gọn hơn
`tsx
// OK nhưng bundle lớn hơn
import { ContactForm, PaymentMethod, BlogModule } from '@ignitech/modules';
`
$3
Khi thêm module mới (ví dụ: Blog), cần:
1. Tạo module trong src/blog/
2. Export từ src/blog/index.ts
3. Thêm vào src/index.ts (optional - để hỗ trợ main import)
4. Thêm subpath export vào package.json:
`json
"./blog": {
"types": "./dist/blog/index.d.ts",
"import": "./dist/blog/index.esm.js",
"require": "./dist/blog/index.js"
}
`
5. Thêm entry point vào tsup.config.ts`