import React, { useEffect, useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; import { api } from '../lib/api'; import type { ApiResponse } from '../lib/api'; import { Cog6ToothIcon, CheckCircleIcon } from '@heroicons/react/24/outline'; // ── Schema ──────────────────────────────────────────────────────────────── const schema = z.object({ site_name: z.string().min(1, 'نام سایت الزامی است'), support_phone: z.string(), commission_enabled: z.string(), commission_percent: z.string().refine(v => { const n = Number(v); return !isNaN(n) && n >= 0 && n <= 100; }, 'درصد باید بین ۰ تا ۱۰۰ باشد'), max_cancel_hours_before: z.string(), appointment_reminder_hours: z.string(), // payment gateways payment_test_mode: z.string(), mellat_terminal_id: z.string(), mellat_username: z.string(), mellat_password: z.string(), sep_terminal_id: z.string(), // sms sms_provider: z.string(), kavenegar_api_key: z.string(), kavenegar_sender: z.string(), sms_price_rials: z.string(), }); type FormValues = z.infer; interface Settings { site_name: string; support_phone: string; commission_enabled: string; commission_percent: string; max_cancel_hours_before: string; appointment_reminder_hours: string; payment_test_mode: string; mellat_terminal_id: string; mellat_username: string; mellat_password: string; sep_terminal_id: string; sms_provider: string; kavenegar_api_key: string; kavenegar_sender: string; sms_price_rials: string; } // ── Component ───────────────────────────────────────────────────────────── export default function SettingsPage() { const qc = useQueryClient(); const [showMellatPassword, setShowMellatPassword] = useState(false); const [showKavenegarKey, setShowKavenegarKey] = useState(false); const { data, isLoading } = useQuery({ queryKey: ['admin-settings'], queryFn: () => api.get>('/api/v1/admin/settings'), staleTime: 30_000, }); // eslint-disable-next-line @typescript-eslint/no-explicit-any const settings: Settings | undefined = (data?.data as any)?.data ?? data?.data; const { register, handleSubmit, reset, watch, setValue, formState: { errors, isDirty }, } = useForm({ resolver: zodResolver(schema) }); useEffect(() => { if (settings) { reset({ site_name: settings.site_name ?? 'ClinicPro', support_phone: settings.support_phone ?? '', commission_enabled: settings.commission_enabled ?? '0', commission_percent: settings.commission_percent ?? '0', max_cancel_hours_before: settings.max_cancel_hours_before ?? '24', appointment_reminder_hours: settings.appointment_reminder_hours ?? '2', payment_test_mode: settings.payment_test_mode ?? '0', mellat_terminal_id: settings.mellat_terminal_id ?? '', mellat_username: settings.mellat_username ?? '', mellat_password: settings.mellat_password ?? '', sep_terminal_id: settings.sep_terminal_id ?? '', sms_provider: settings.sms_provider ?? 'kavenegar', kavenegar_api_key: settings.kavenegar_api_key ?? '', kavenegar_sender: settings.kavenegar_sender ?? '', sms_price_rials: settings.sms_price_rials ?? '500', }); } }, [settings, reset]); const mutation = useMutation({ mutationFn: (values: FormValues) => api.patch>('/api/v1/admin/settings', values), onSuccess: () => { qc.invalidateQueries({ queryKey: ['admin-settings'] }); }, }); const commissionEnabled = watch('commission_enabled') === '1'; const paymentTestMode = watch('payment_test_mode') === '1'; const onSubmit = (values: FormValues) => { mutation.mutate(values); }; if (isLoading) { return (
{Array.from({ length: 3 }).map((_, i) => (
))}
); } return (

تنظیمات سایت

پیکربندی کلی پلتفرم
{mutation.isSuccess && (
تنظیمات ذخیره شد
)}
{/* اطلاعات پایه */}

اطلاعات پایه

{errors.site_name &&

{errors.site_name.message}

}
{/* تنظیمات کمیسیون */}
٪

کمیسیون سایت

{/* toggle فعال/غیرفعال */}
{/* تنظیمات نوبت‌دهی */}

تنظیمات نوبت‌دهی

ساعت قبل از نوبت
ساعت قبل از نوبت
{/* درگاه پرداخت */}
💳

درگاه پرداخت

{/* حالت تست */}
{/* تنظیمات پیامک */}
📱

تنظیمات پیامک (SMS)

تنظیمات کاوه‌نگار
{/* دکمه ذخیره */}
); }