diff --git a/assets/admin/pages/RepresentationsPage.tsx b/assets/admin/pages/RepresentationsPage.tsx index 44bbb779..a4bf361b 100644 --- a/assets/admin/pages/RepresentationsPage.tsx +++ b/assets/admin/pages/RepresentationsPage.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; -import { EyeIcon, TrashIcon, PlusIcon, MagnifyingGlassIcon } from '@heroicons/react/24/outline'; +import { EyeIcon, NoSymbolIcon, PlusIcon, MagnifyingGlassIcon } from '@heroicons/react/24/outline'; import { useForm, Controller } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; @@ -75,10 +75,11 @@ export default function RepresentationsPage() { onError: (err: Error) => toast.error(err.message), }); - const deleteMutation = useMutation({ - mutationFn: (r: Representation) => api.delete>(`/api/v1/representation/${r.uuid}`), + const deactivateMutation = useMutation({ + mutationFn: (r: Representation) => + api.patch>(`/api/v1/representation/${r.uuid}`, { active: false }), onSuccess: () => { - toast.success('نماینده حذف شد'); + toast.success('نماینده غیرفعال شد'); setDeleteTarget(null); qc.invalidateQueries({ queryKey: ['representations'] }); }, @@ -146,10 +147,12 @@ export default function RepresentationsPage() { className="mini-btn" title="مشاهده"> - + {(rep.is_active ?? rep.active) && ( + + )} )} /> @@ -206,12 +209,12 @@ export default function RepresentationsPage() { deleteTarget && deleteMutation.mutate(deleteTarget)} + loading={deactivateMutation.isPending} + onConfirm={() => deleteTarget && deactivateMutation.mutate(deleteTarget)} onCancel={() => setDeleteTarget(null)} /> diff --git a/docs/api/admin.md b/docs/api/admin.md index 54288929..c096ae63 100644 --- a/docs/api/admin.md +++ b/docs/api/admin.md @@ -621,12 +621,30 @@ List all representations. | Param | Type | Required | Description | |-------|------|----------|-------------| | `page` | integer | ❌ | Default: 1 | -| `limit` | integer | ❌ | Default: 20 | -| `search` | string | ❌ | Search by name | +| `limit` | integer | ❌ | Default: 15 | +| `search` | string | ❌ | Search by name or mobile (representation's or linked user's) | | `city_id` | integer | ❌ | Filter by city | ### Response `200` -Paginated representation list. +Paginated representation list. Each item: +```json +{ + "id": 3, + "uuid": "...", + "full_name": "حامد حسینی", + "mobile_number": "09120671756", + "city_id": 132, + "city": "یزد", + "commission_percent": 10.0, + "wallet_balance": 0, + "is_active": true, + "created_at": "2026-06-18T..." +} +``` + +> `mobile_number` falls back to the linked user's mobile when the representation's own `mobile_number` column is empty. + +> **Deactivation, not deletion:** the admin panel deactivates a representation via `PATCH /api/v1/representation/{uuid}` with `{ "active": false }` rather than calling `DELETE`. --- diff --git a/src/Admin/Controller/AdminApiController.php b/src/Admin/Controller/AdminApiController.php index 10d264d3..d1086986 100644 --- a/src/Admin/Controller/AdminApiController.php +++ b/src/Admin/Controller/AdminApiController.php @@ -921,13 +921,14 @@ class AdminApiController extends BaseController $cityId = $request->query->get('city_id'); $qb = $this->em->createQueryBuilder() - ->select('r.id, r.uuid, r.fullName, r.mobileNumber, r.cityId, r.commissionPercent, r.active, r.createdAt, c.name as city_name') + ->select('r.id, r.uuid, r.fullName, r.mobileNumber, u.mobileNumber as user_mobile, r.cityId, r.commissionPercent, r.active, r.createdAt, c.name as city_name') ->from(Representation::class, 'r') + ->join('r.user', 'u') ->leftJoin(City::class, 'c', 'WITH', 'c.id = r.cityId') ->orderBy('r.createdAt', 'DESC'); if ($search !== '') { - $qb->andWhere('r.fullName LIKE :s OR r.mobileNumber LIKE :s') + $qb->andWhere('r.fullName LIKE :s OR r.mobileNumber LIKE :s OR u.mobileNumber LIKE :s') ->setParameter('s', '%' . $search . '%'); } @@ -946,7 +947,7 @@ class AdminApiController extends BaseController 'uuid' => $r['uuid'], 'domain' => $r['fullName'], 'full_name' => $r['fullName'], - 'mobile_number' => $r['mobileNumber'], + 'mobile_number' => $r['mobileNumber'] ?: ($r['user_mobile'] ?? null), 'city_id' => $r['cityId'], 'city' => $r['city_name'] ?? null, 'commission_percent' => (float) $r['commissionPercent'],