feat(admin): replace all remaining action buttons with Button component
All checks were successful
Deploy Canina / deploy (push) Successful in 29s
All checks were successful
Deploy Canina / deploy (push) Successful in 29s
This commit is contained in:
parent
1350267ffb
commit
33c1bee483
@ -201,10 +201,23 @@ export default function Blogs() {
|
||||
</td>
|
||||
<td className="py-4 px-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<button onClick={() => openModal(blog)} className="p-2 text-blue-600 hover:bg-blue-50 rounded-lg transition-colors cursor-pointer"><Edit2 className="w-4 h-4" /></button>
|
||||
<button onClick={() => setDeleteTargetId(blog.id)} className="p-2 text-red-600 hover:bg-red-50 rounded-lg transition-colors cursor-pointer"><Trash2 className="w-4 h-4" /></button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Edit2}
|
||||
onClick={() => openModal(blog)}
|
||||
className="text-blue-600 hover:bg-blue-50"
|
||||
/>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Trash2}
|
||||
onClick={() => setDeleteTargetId(blog.id)}
|
||||
className="text-red-600 hover:bg-red-50"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
))
|
||||
)}
|
||||
|
||||
@ -2,6 +2,8 @@ import React, { useState, useEffect } from 'react';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import api from '../services/api';
|
||||
import ConfirmModal from '../components/ui/ConfirmModal';
|
||||
import Button from '../components/ui/Button';
|
||||
|
||||
|
||||
export interface HeroBanner {
|
||||
id: string;
|
||||
@ -165,9 +167,9 @@ export default function CMS() {
|
||||
<label className="block text-xs font-bold text-gray-600 mb-1">آدرس تصویر (URL)</label>
|
||||
<input value={newImageUrl} onChange={e => setNewImageUrl(e.target.value)} className="w-full border rounded-xl p-2.5 text-sm" placeholder="/assets/images/..." />
|
||||
</div>
|
||||
<button type="submit" className="bg-blue-600 text-white font-bold px-6 py-2.5 rounded-xl hover:bg-blue-700 text-sm">
|
||||
<Button type="submit" variant="primary" size="md">
|
||||
ثبت بنر جدید
|
||||
</button>
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
@ -177,9 +179,14 @@ export default function CMS() {
|
||||
<h4 className="font-bold text-gray-900">{b.title}</h4>
|
||||
<p className="text-xs text-gray-500 mt-1">{b.subtitle}</p>
|
||||
</div>
|
||||
<button onClick={() => setDeleteBannerId(b.id)} className="text-red-500 text-xs font-bold bg-red-50 px-3 py-1.5 rounded-lg hover:bg-red-100">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
onClick={() => setDeleteBannerId(b.id)}
|
||||
className="text-red-500 hover:bg-red-50"
|
||||
>
|
||||
حذف
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@ -204,9 +211,9 @@ export default function CMS() {
|
||||
<label className="block text-xs font-bold text-gray-600 mb-1">متن نظر و تجربه علمی</label>
|
||||
<textarea required value={quote} onChange={e => setQuote(e.target.value)} className="w-full border rounded-xl p-2.5 text-sm" rows={3} placeholder="تجربه استفاده از Canhydrox GAG..." />
|
||||
</div>
|
||||
<button type="submit" className="bg-blue-600 text-white font-bold px-6 py-2.5 rounded-xl hover:bg-blue-700 text-sm">
|
||||
<Button type="submit" variant="primary" size="md">
|
||||
ثبت نظر جدید
|
||||
</button>
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
@ -216,15 +223,21 @@ export default function CMS() {
|
||||
<h4 className="font-bold text-gray-900">{t.vetName} — <span className="text-blue-600">{t.clinicName}</span></h4>
|
||||
<p className="text-xs text-gray-600 mt-2 font-medium">"{t.quote}"</p>
|
||||
</div>
|
||||
<button onClick={() => setDeleteTestimonialId(t.id)} className="text-red-500 text-xs font-bold bg-red-50 px-3 py-1.5 rounded-lg hover:bg-red-100">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
onClick={() => setDeleteTestimonialId(t.id)}
|
||||
className="text-red-500 hover:bg-red-50"
|
||||
>
|
||||
حذف
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
<ConfirmModal
|
||||
isOpen={!!deleteBannerId}
|
||||
title="حذف بنر"
|
||||
|
||||
@ -203,14 +203,23 @@ export default function Categories() {
|
||||
</td>
|
||||
<td className="py-4 px-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<button onClick={() => openModal(cat)} className="p-2 text-blue-600 hover:bg-blue-50 rounded-lg transition-colors cursor-pointer">
|
||||
<Edit2 className="w-4 h-4" />
|
||||
</button>
|
||||
<button onClick={() => setDeleteTargetId(cat.id)} className="p-2 text-red-600 hover:bg-red-50 rounded-lg transition-colors cursor-pointer">
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Edit2}
|
||||
onClick={() => openModal(cat)}
|
||||
className="text-blue-600 hover:bg-blue-50"
|
||||
/>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Trash2}
|
||||
onClick={() => setDeleteTargetId(cat.id)}
|
||||
className="text-red-600 hover:bg-red-50"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
))
|
||||
)}
|
||||
|
||||
@ -218,17 +218,34 @@ export default function Coupons() {
|
||||
{c.maxUses && <span className="text-gray-400 text-xs mr-1">/ {c.maxUses}</span>}
|
||||
</td>
|
||||
<td className="py-4 px-6">
|
||||
<button onClick={() => handleToggle(c.id, c.isActive)} className={`px-3 py-1 text-xs font-bold rounded-lg transition-colors flex items-center gap-1 ${c.isActive ? 'bg-green-100 text-green-700 hover:bg-green-200' : 'bg-gray-100 text-gray-600 hover:bg-gray-200'}`}>
|
||||
{c.isActive ? <CheckCircle2 className="w-3 h-3" /> : <XCircle className="w-3 h-3" />}
|
||||
<Button
|
||||
variant={c.isActive ? 'primary' : 'secondary'}
|
||||
size="xs"
|
||||
startIcon={c.isActive ? CheckCircle2 : XCircle}
|
||||
onClick={() => handleToggle(c.id, c.isActive)}
|
||||
>
|
||||
{c.isActive ? 'فعال' : 'غیرفعال'}
|
||||
</button>
|
||||
</Button>
|
||||
</td>
|
||||
<td className="py-4 px-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<button onClick={() => openModal(c)} className="p-2 text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"><Edit2 className="w-4 h-4" /></button>
|
||||
<button onClick={() => setDeleteTargetId(c.id)} className="p-2 text-red-600 hover:bg-red-50 rounded-lg transition-colors"><Trash2 className="w-4 h-4" /></button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Edit2}
|
||||
onClick={() => openModal(c)}
|
||||
className="text-blue-600 hover:bg-blue-50"
|
||||
/>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Trash2}
|
||||
onClick={() => setDeleteTargetId(c.id)}
|
||||
className="text-red-600 hover:bg-red-50"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
))
|
||||
)}
|
||||
@ -456,9 +473,15 @@ function CouponModal({ formData, setFormData, onSave, onClose, isEditing }: Coup
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between border-b border-gray-100 pb-2">
|
||||
<h4 className="font-bold text-gray-800">اهداف اختصاصی (Targets & Modifiers)</h4>
|
||||
<button type="button" onClick={addTarget} className="text-xs font-bold text-purple-600 bg-purple-50 px-3 py-1.5 rounded-xl hover:bg-purple-100 transition-colors flex items-center gap-1 cursor-pointer">
|
||||
<Plus className="w-4 h-4" /> افزودن هدف
|
||||
</button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="xs"
|
||||
startIcon={Plus}
|
||||
onClick={addTarget}
|
||||
>
|
||||
افزودن هدف
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{formData.targets.length === 0 ? (
|
||||
@ -499,13 +522,19 @@ function CouponModal({ formData, setFormData, onSave, onClose, isEditing }: Coup
|
||||
<input type="number" placeholder="مقدار پایه" value={t.modifierValue} onChange={(e) => updateTarget(i, 'modifierValue', e.target.value)} dir="ltr" className="w-full px-2.5 py-2 rounded-xl border border-gray-200 text-xs outline-none focus:border-purple-500" />
|
||||
</div>
|
||||
|
||||
<button type="button" onClick={() => removeTarget(i)} className="p-2.5 text-red-500 bg-red-50 hover:bg-red-100 rounded-xl transition-colors shrink-0 cursor-pointer">
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Trash2}
|
||||
onClick={() => removeTarget(i)}
|
||||
className="text-red-500 hover:bg-red-50"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
|
||||
<div className="flex items-center">
|
||||
|
||||
@ -233,14 +233,23 @@ export default function IngredientsManager() {
|
||||
</td>
|
||||
<td className="py-4 px-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<button onClick={() => openModal(item)} className="p-2 text-blue-600 hover:bg-blue-50 rounded-lg transition-colors">
|
||||
<Edit2 className="w-4 h-4" />
|
||||
</button>
|
||||
<button onClick={() => setDeleteTargetId(item.id)} className="p-2 text-red-600 hover:bg-red-50 rounded-lg transition-colors">
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Edit2}
|
||||
onClick={() => openModal(item)}
|
||||
className="text-blue-600 hover:bg-blue-50"
|
||||
/>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Trash2}
|
||||
onClick={() => setDeleteTargetId(item.id)}
|
||||
className="text-red-600 hover:bg-red-50"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
))
|
||||
)}
|
||||
|
||||
@ -282,14 +282,23 @@ export default function MenuManager() {
|
||||
<span className="text-xs text-gray-400 font-mono">{child.href}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<button onClick={() => openModal(child)} className="p-1.5 text-blue-600 hover:bg-blue-50 rounded-lg">
|
||||
<Edit2 className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
<button onClick={() => setDeleteTargetId(child.id)} className="p-1.5 text-red-500 hover:bg-red-50 rounded-lg">
|
||||
<Trash2 className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Edit2}
|
||||
onClick={() => openModal(child)}
|
||||
className="text-blue-600 hover:bg-blue-50"
|
||||
/>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Trash2}
|
||||
onClick={() => setDeleteTargetId(child.id)}
|
||||
className="text-red-500 hover:bg-red-50"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -719,38 +719,41 @@ export default function Orders() {
|
||||
</td>
|
||||
<td className="py-4 px-6">
|
||||
<div className="flex items-center justify-center gap-1.5">
|
||||
<button
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Eye}
|
||||
onClick={() => openOrderModal(order)}
|
||||
className="text-purple-600 hover:bg-purple-50 p-2 rounded-xl transition-colors flex items-center gap-1 font-bold text-xs cursor-pointer"
|
||||
title="مشاهده فاکتور و جزئیات کامل"
|
||||
disabled={isProcessing}
|
||||
className="text-purple-600 hover:bg-purple-50"
|
||||
>
|
||||
<Eye className="w-4 h-4" />
|
||||
<span>جزئیات</span>
|
||||
</button>
|
||||
جزئیات
|
||||
</Button>
|
||||
|
||||
<button
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Printer}
|
||||
onClick={() => handlePrintInvoice(order)}
|
||||
className="text-gray-600 hover:bg-gray-100 p-2 rounded-xl transition-colors cursor-pointer"
|
||||
title="چاپ فوری فاکتور رسمی"
|
||||
disabled={isProcessing}
|
||||
>
|
||||
<Printer className="w-4 h-4" />
|
||||
</button>
|
||||
className="text-gray-600 hover:bg-gray-100"
|
||||
/>
|
||||
|
||||
{(order.status === 'cancelled' || order.status === 'pending_payment') && (
|
||||
<button
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Undo2}
|
||||
onClick={() => openOrderRefundModal(order)}
|
||||
className="text-rose-600 hover:bg-rose-50 p-2 rounded-xl transition-colors flex items-center gap-1 font-bold text-xs cursor-pointer"
|
||||
title="استرداد وجه به کاربر (کیف پول / شاپرک)"
|
||||
disabled={isProcessing}
|
||||
className="text-rose-600 hover:bg-rose-50"
|
||||
>
|
||||
<Undo2 className="w-4 h-4" />
|
||||
<span>استرداد</span>
|
||||
</button>
|
||||
استرداد
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
|
||||
@ -602,14 +602,23 @@ export default function Products() {
|
||||
</td>
|
||||
<td className="py-4 px-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<button onClick={() => openModal(product)} className="p-2 text-blue-600 hover:bg-blue-50 rounded-lg transition-colors">
|
||||
<Edit2 className="w-4 h-4" />
|
||||
</button>
|
||||
<button onClick={() => setDeleteTargetId(product.id)} className="p-2 text-red-600 hover:bg-red-50 rounded-lg transition-colors">
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Edit2}
|
||||
onClick={() => openModal(product)}
|
||||
className="text-blue-600 hover:bg-blue-50"
|
||||
/>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Trash2}
|
||||
onClick={() => setDeleteTargetId(product.id)}
|
||||
className="text-red-600 hover:bg-red-50"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
))
|
||||
)}
|
||||
|
||||
@ -188,9 +188,22 @@ export default function Wiki() {
|
||||
<td className="py-4 px-6 text-gray-500 text-sm max-w-xs truncate">{t.definition}</td>
|
||||
<td className="py-4 px-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<button onClick={() => openModal(t)} className="p-2 text-blue-600 hover:bg-blue-50 rounded-lg transition-colors cursor-pointer"><Edit2 className="w-4 h-4" /></button>
|
||||
<button onClick={() => setDeleteTargetKey(t.key)} className="p-2 text-red-600 hover:bg-red-50 rounded-lg transition-colors cursor-pointer"><Trash2 className="w-4 h-4" /></button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Edit2}
|
||||
onClick={() => openModal(t)}
|
||||
className="text-blue-600 hover:bg-blue-50"
|
||||
/>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
startIcon={Trash2}
|
||||
onClick={() => setDeleteTargetKey(t.key)}
|
||||
className="text-red-600 hover:bg-red-50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user