From 87d94801f89032d43ad7476ba44dc6f27ca4e6fc Mon Sep 17 00:00:00 2001 From: hamed <15238-genius.ha@users.noreply.drupalcode.org> Date: Sun, 5 Jul 2026 11:27:10 +0330 Subject: [PATCH] feat: add Kavenegar template guide and update PreRegistrationController to use appUrl --- assets/admin/pages/SmsPage.tsx | 72 ++++++++++++++++++- config/services.yaml | 4 ++ .../Controller/PreRegistrationController.php | 3 +- 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/assets/admin/pages/SmsPage.tsx b/assets/admin/pages/SmsPage.tsx index 41fdcd00..9060a8a1 100644 --- a/assets/admin/pages/SmsPage.tsx +++ b/assets/admin/pages/SmsPage.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; -import { CheckIcon, XMarkIcon, TrashIcon, PlusIcon, PencilIcon } from '@heroicons/react/24/outline'; +import { CheckIcon, XMarkIcon, TrashIcon, PlusIcon, PencilIcon, ClipboardDocumentIcon } from '@heroicons/react/24/outline'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; @@ -45,6 +45,75 @@ const TAG_FILTER_OPTIONS = [ ...Object.entries(TAG_LABELS).map(([value, label]) => ({ value, label })), ]; +// الگوی تمپلت کاوه‌نگار را از body (با {var}) و token_map (var→slot) می‌سازد: +// هر {var} با %slot جایگزین می‌شود. +function buildKavenegarPattern(body: string, tokenMap: Record): string { + return body.replace(/\{([a-zA-Z0-9_]+)\}/g, (whole, key) => + tokenMap[key] ? `%${tokenMap[key]}` : whole, + ); +} + +function KavenegarGuide({ msg }: { msg: SmsMessageText }) { + const tokenMap = msg.token_map ?? {}; + const pattern = buildKavenegarPattern(msg.body, tokenMap); + const templateName = msg.kavenegar_template ?? ''; + + const copy = (text: string, label: string) => { + navigator.clipboard.writeText(text).then( + () => toast.success(`${label} کپی شد`), + () => toast.error('کپی ناموفق بود'), + ); + }; + + return ( +
+ + نحوه تعریف این تمپلت در پنل کاوه‌نگار + +
+
+ در پنل کاوه‌نگار → بخش «الگوها» یک الگوی جدید با نام و متن زیر بسازید و تأیید بگیرید. + متن واقعی پیامک از همین الگو ارسال می‌شود. +
+ +
+ نام الگو: + {templateName || '—'} + +
+ +
+
+ متن الگو (با %token): + +
+
+            {pattern}
+          
+
+ + {Object.keys(tokenMap).length > 0 && ( +
+ نگاشت متغیرها: + {Object.entries(tokenMap).map(([k, slot]) => ( + {`{${k}} → %${slot}`} + ))} +
+ )} + +
+ توجه: token، token2، token3 فاصله نمی‌پذیرند؛ + مقادیر دارای فاصله در token10/token20 قرار می‌گیرند. +
+
+
+ ); +} + export default function SmsPage() { const qc = useQueryClient(); const [activeTab, setActiveTab] = useState('samples'); @@ -497,6 +566,7 @@ export default function SmsPage() { {m.kavenegar_template || 'تعریف‌نشده'} + {m.variables.length > 0 && (
{m.variables.map((v) => {`{${v}}`})} diff --git a/config/services.yaml b/config/services.yaml index 9deaca1a..0c09d993 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -112,6 +112,10 @@ services: arguments: $appUrl: '%env(APP_BASE_URL)%' + App\Auth\Controller\PreRegistrationController: + arguments: + $appUrl: '%env(APP_BASE_URL)%' + App\Sms\Controller\SmsWalletController: arguments: $appBaseUrl: '%env(APP_BASE_URL)%' diff --git a/src/Auth/Controller/PreRegistrationController.php b/src/Auth/Controller/PreRegistrationController.php index 2bda849c..805e8785 100644 --- a/src/Auth/Controller/PreRegistrationController.php +++ b/src/Auth/Controller/PreRegistrationController.php @@ -34,6 +34,7 @@ class PreRegistrationController extends BaseController private readonly UserPasswordHasherInterface $hasher, private readonly SmsService $sms, private readonly LoggerInterface $logger, + private readonly string $appUrl, ) {} #[Route('/api/v1/pre-registration', methods: ['POST'])] @@ -160,7 +161,7 @@ class PreRegistrationController extends BaseController [ 'username' => $preReg->getMobile(), 'password' => $password, - 'link' => 'https://clinic-pro.ddev.site/admin', + 'link' => rtrim($this->appUrl, '/') . '/admin', ], ); } catch (\Throwable $e) {