# دليل ربط الصفحات بالـ API - مرجع المطور

## الهيكل العام

```
src/
├── constants/endpoints.ts     ← كل مسارات API في مكان واحد
├── lib/api.ts                 ← Axios client مع interceptors
├── hooks/                     ← Custom hooks لكل كيان
│   ├── useEntityBase.ts       ← Factory hook لـ CRUD العام
│   ├── useCustomers.ts
│   ├── useKyc.ts
│   ├── useOrders.ts
│   ├── useDashboard.ts
│   ├── useVaults.ts
│   ├── useAuditLogs.ts
│   ├── usePricing.ts
│   ├── useTransfers.ts
│   ├── useRedemptions.ts
│   ├── useWallets.ts
│   ├── useForm.ts             ← إدارة حالة النماذج مع Zod
│   ├── useDebounce.ts
│   └── index.ts               ← Barrel export
├── types/base.ts              ← BaseEntity, PaginatedResponse, UseEntityHookReturn, FormField
├── components/
│   ├── ui/BaseListPage.tsx    ← صفحة قائمة CRUD عامة
│   ├── ui/BaseForm.tsx        ← نموذج عام ديناميكي
│   ├── ui/FormFields.tsx      ← حقول إدخال فردية
│   ├── ui/Pagination.tsx     ← ترقيم صفحات
│   ├── ErrorBoundary.tsx      ← معالجة أخطاء React
│   ├── ErrorMessage.tsx       ← عرض أخطاء inline
│   └── protected-route.tsx    ← حماية مسارات حسب الأدوار
├── contexts/auth-context.tsx  ← AuthProvider + useAuth
└── lib/validators.ts          ← Zod schemas للتحقق
```

---

## تدفق البيانات: من API إلى الصفحة

```
┌─────────────┐     ┌──────────────┐     ┌─────────────┐     ┌──────────┐
│  Endpoint   │────▶│   api.ts     │────▶│   Hook      │────▶│  الصفحة   │
│ (constants) │     │  (Axios)     │     │ (useEntity) │     │ (Client) │
└─────────────┘     └──────────────┘     └─────────────┘     └──────────┘
```

### الخطوة 1: تعريف المسار في `constants/endpoints.ts`

```typescript
// src/constants/endpoints.ts
export const ENDPOINTS = {
  CUSTOMERS: {
    LIST: '/customers',
    CREATE: '/customers',
    GET_BY_ID: (id: string): string => `/customers/${id}`,
    UPDATE: (id: string): string => `/customers/${id}`,
    DELETE: (id: string): string => `/customers/${id}`,
  },
  // ...
}
```

### الخطوة 2: إنشاء Hook للكيان

```typescript
// src/hooks/useCustomers.ts
import { createEntityHook } from './useEntityBase';
import type { CustomerDTO } from '@/lib/api/types';

export type CustomerCreateDTO = Omit<CustomerDTO, 'id' | 'registered_at' | 'last_login_at'>;
export type CustomerUpdateDTO = Partial<CustomerCreateDTO>;

export const useCustomers = createEntityHook<CustomerDTO, CustomerCreateDTO, CustomerUpdateDTO>(
  'العملاء',
  '/customers',
);
```

### الخطوة 3: استخدام Hook في الصفحة (Client Component)

```tsx
// src/app/(admin)/customers/page.tsx
'use client';

import { useEffect } from 'react';
import { useCustomers } from '@/hooks';
import { BaseListPage } from '@/components/ui/BaseListPage';
// ... أو بناء الصفحة يدوياً

export default function CustomersPage() {
  const {
    items, isLoading, error,
    currentPage, totalCount, pageSize, totalPages, searchTerm,
    fetchItems, setSearchTerm, setCurrentPage, setPageSize,
  } = useCustomers();

  useEffect(() => {
    fetchItems(1, 10);
  }, []);

  if (isLoading) return <LoadingSpinner />;
  if (error) return <ErrorMessage message={error} />;

  return (
    <BaseListPage
      entityName="عملاء"
      items={items}
      isLoading={isLoading}
      error={error}
      currentPage={currentPage}
      totalCount={totalCount}
      pageSize={pageSize}
      totalPages={totalPages}
      searchTerm={searchTerm}
      onPageChange={setCurrentPage}
      onPageSizeChange={setPageSize}
      onSearchChange={setSearchTerm}
      columns={[
        { key: 'customer_code', label: 'رقم العميل' },
        { key: 'name', label: 'الاسم' },
        { key: 'tier', label: 'النوع' },
      ]}
      onView={(item) => router.push(`/customers/${item.id}`)}
      onCreate={() => router.push('/customers/create')}
    />
  );
}
```

---

## أنماط الاستخدام الشائعة

### 1. صفحة قائمة مع CRUD كامل (استخدام BaseListPage)

```tsx
'use client';
import { useCustomers } from '@/hooks';
import { BaseListPage } from '@/components/ui/BaseListPage';

export default function CustomersPage() {
  const hook = useCustomers();

  useEffect(() => { hook.fetchItems(1, 10); }, []);

  return <BaseListPage entityName="عملاء" hook={hook} columns={[...]} />;
}
```

### 2. صفحة قائمة مخصصة (بدون BaseListPage)

```tsx
'use client';
import { useOrders } from '@/hooks';
import { DataTable } from '@/components/ui/data-table';
import { Pagination } from '@/components/ui/Pagination';

export default function OrdersPage() {
  const { items, isLoading, error, fetchItems, currentPage, totalPages, onPageChange } = useOrders();

  useEffect(() => { fetchItems(1, 10); }, []);

  return (
    <>
      <DataTable columns={columns} data={items} isLoading={isLoading} />
      <Pagination currentPage={currentPage} totalPages={totalPages} onPageChange={onPageChange} />
    </>
  );
}
```

### 3. صفحة بيانات غير CRUD (مثل Dashboard)

```tsx
'use client';
import { useDashboard } from '@/hooks';

export default function DashboardPage() {
  const { overview, activity, isLoading, error, fetchOverview, fetchActivity } = useDashboard();

  useEffect(() => { fetchOverview(); fetchActivity(); }, []);

  if (isLoading) return <Loading />;
  if (error) return <ErrorMessage message={error} />;

  return (
    <div className="grid grid-cols-4 gap-4">
      <KpiCard label="إجمالي الأصول" value={overview?.totalAssetsUsd} />
      {/* ... */}
    </div>
  );
}
```

### 4. نموذج إنشاء/تعديل (مع useForm + Zod)

```tsx
'use client';
import { useForm } from '@/hooks';
import { z } from 'zod';
import { BaseForm } from '@/components/ui/BaseForm';
import { useCustomers } from '@/hooks';

const customerSchema = z.object({
  name: z.string().min(2, 'يجب أن يكون الاسم حرفين على الأقل'),
  email: z.string().email('بريد إلكتروني غير صحيح'),
  phone: z.string().min(10, 'رقم هاتف غير صحيح'),
  tier: z.enum(['retail', 'premium', 'institutional']),
});

export default function CreateCustomerPage() {
  const { createItem } = useCustomers();
  const form = useForm({
    initialValues: { name: '', email: '', phone: '', tier: 'retail' },
    validationSchema: customerSchema,
    onSubmit: async (values) => {
      await createItem(values);
    },
  });

  return (
    <BaseForm
      fields={[
        { name: 'name', label: 'الاسم', type: 'text', required: true },
        { name: 'email', label: 'البريد الإلكتروني', type: 'email', required: true },
        { name: 'phone', label: 'الهاتف', type: 'text', required: true },
        {
          name: 'tier', label: 'النوع', type: 'select', required: true,
          options: [
            { value: 'retail', label: 'فردي' },
            { value: 'premium', label: 'متميز' },
            { value: 'institutional', label: 'مؤسسي' },
          ],
        },
      ]}
      values={form.values}
      errors={form.errors}
      isLoading={form.isSubmitting}
      onFieldChange={(name, value) => form.setValue(name as keyof typeof form.values, value)}
      onSubmit={form.handleSubmit}
      submitLabel="إنشاء عميل"
    />
  );
}
```

---

## تحويل صفحة من Supabase إلى API

### قبل (Server Component + Supabase):

```tsx
// ❌ النمط القديم
export default async function CustomersPage() {
  const supabase = await createClient()
  const { data } = await supabase.from("customers").select("*").limit(50)
  return <table>{data.map(c => <tr key={c.id}>{c.name}</tr>)}</table>
}
```

### بعد (Client Component + Hook):

```tsx
// ✅ النمط الجديد
'use client';
import { useEffect } from 'react';
import { useCustomers } from '@/hooks';
import { ErrorMessage } from '@/components/ErrorMessage';

export default function CustomersPage() {
  const { items, isLoading, error, fetchItems } = useCustomers();

  useEffect(() => { fetchItems(1, 10); }, []);

  if (isLoading) return <LoadingSpinner />;
  if (error) return <ErrorMessage message={error} />;

  return <table>{items.map(c => <tr key={c.id}>{c.name}</tr>)}</table>;
}
```

### التغييرات المطلوبة لكل صفحة:

| الخطوة | التفاصيل |
|---|---|
| 1. إضافة `'use client'` | في أعلى الملف (الصفحة تصبح Client Component) |
| 2. حذف `export const dynamic` | لم يعد هناك Server Component |
| 3. حذف `createClient()` | لم يعد هناك Supabase مباشر |
| 4. حذف `await Promise.all([...])` | البيانات تأتي من Hook |
| 5. استخدام `useEntity hook` | `const { items, ... } = useCustomers()` |
| 6. إضافة `useEffect` | لاستدعاء `fetchItems(1, 10)` عند التحميل |
| 7. معالجة الحالات | إضافة `isLoading` و `error` في الـ JSX |
| 8. KPI data | يجب أن يوفرها endpoint الـ API أو يمكن حسابها من `items` |

---

## API Response Format المتوقع

جميع endpoints تعيد نفس الهيكل:

### Paginated List Response:
```json
{
  "success": true,
  "data": {
    "items": [...],
    "total": 100,
    "page": 1,
    "page_size": 10,
    "pages": 10
  }
}
```

### Single Item Response:
```json
{
  "success": true,
  "data": { "id": "...", "name": "...", ... }
}
```

### Error Response:
```json
{
  "success": false,
  "message": "رسالة الخطأ بالعربي"
}
```

---

## Quick Reference: Imports الشائعة

```typescript
// API & Endpoints
import { api } from '@/lib/api';
import { ENDPOINTS } from '@/constants/endpoints';

// Hooks
import { useCustomers, useKyc, useOrders, useVaults, useDashboard, useAuditLogs, usePricing, useTransfers, useRedemptions, useWallets } from '@/hooks';
import { useForm, useDebounce } from '@/hooks';

// Types
import type { UseEntityHookReturn, FormField, PaginatedResponse } from '@/types';

// UI Components
import { BaseListPage } from '@/components/ui/BaseListPage';
import { BaseForm } from '@/components/ui/BaseForm';
import { InputField, TextAreaField, SelectField } from '@/components/ui/FormFields';
import { Pagination } from '@/components/ui/Pagination';
import { ErrorMessage } from '@/components/ErrorMessage';
import ErrorBoundary from '@/components/ErrorBoundary';

// Auth
import { useAuth } from '@/contexts/auth-context';
import { ProtectedRoute } from '@/components/protected-route';

// Existing UI (continue using)
import { KpiCard } from '@/components/ui/kpi-card';
import { PageHeader } from '@/components/ui/page-header';
import { SectionCard } from '@/components/ui/section-card';
import { DataTable } from '@/components/ui/data-table';
import { StatusBadge } from '@/components/ui/status-badge';
import { FilterToolbar } from '@/components/ui/filter-toolbar';
import { Modal } from '@/components/ui/modal';
import { Button } from '@/components/ui/button';

// Formatters
import { formatMoney, fmtMoney, formatNumber, fmtGrams, formatDateTime, timeAgo } from '@/lib/format';
```

---

## ملاحظات مهمة

1. **الـ Hooks تعمل فقط في Client Components** - أضف `'use client'` في أعلى الصفحة
2. **لا تستخدم Supabase مباشرة** - استخدم `api.get/post/put/del` أو الـ Hooks
3. **كل مسار API معرّف في `ENDPOINTS`** - لا تكتب مسارات API يدوياً في الصفحات
4. **الـ Auth token يُضاف تلقائياً** - الـ Axios interceptor يضيف `Bearer token` من localStorage
5. **الـ 401 redirect تلقائي** - إذا انتهت صلاحية الـ token، يُوجّه المستخدم إلى `/login`
6. **رسائل الخطأ بالعربي** - كل Hook يستخدم `entityName` بالعربي في رسائل الخطأ
7. **الـ DataProvider القديم لا يزال موجوداً** - في `src/lib/data-provider/` لكن لا يُنصح باستخدامه للصفحات الجديدة