From 29a190f02a5b99d11ef0c223c2c31072d64f8702 Mon Sep 17 00:00:00 2001 From: Alireza Hassani Date: Wed, 9 Sep 2026 11:37:35 +0330 Subject: [PATCH] Improve SMS settings layout and add send-modal variable chips. Credit/usage divider, total row plus typed counts grid, and insertable template vars on compose. Co-authored-by: Cursor --- .../src/components/SendCustomerSmsModal.tsx | 43 +++++++++++++++- .../src/components/SmsSettingsSection.tsx | 43 +++++++++------- .../src/pages/SettingsPage.module.css | 50 ++++++++++++++++++- .../src/pages/BusinessesPage.module.css | 40 +++++++++++++++ apps/super-admin/src/pages/BusinessesPage.tsx | 45 +++++++++-------- 5 files changed, 178 insertions(+), 43 deletions(-) diff --git a/apps/business/src/components/SendCustomerSmsModal.tsx b/apps/business/src/components/SendCustomerSmsModal.tsx index 508233b..ae272c1 100644 --- a/apps/business/src/components/SendCustomerSmsModal.tsx +++ b/apps/business/src/components/SendCustomerSmsModal.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react' +import { useEffect, useRef, useState } from 'react' import { createPortal } from 'react-dom' import { X } from 'lucide-react' import { useLocale } from '@meshkee/dashboard-ui' @@ -12,6 +12,7 @@ import { } from '../services/customerService' import { listSmsTemplates, type SmsTemplate } from '../services/smsTemplateService' import modalStyles from './VariationsModal.module.css' +import settingsStyles from '../pages/SettingsPage.module.css' export type SmsComposeTarget = | { mode: 'single'; customer: BusinessCustomerListItem } @@ -27,6 +28,7 @@ interface SendCustomerSmsModalProps { const ANIMATION_MS = 220 const MAX_LEN = 700 +const SMS_VARS = ['{{user.name}}', '{{user.lastname}}', '{{user.title}}'] as const export function SendCustomerSmsModal({ open, @@ -45,6 +47,7 @@ export function SendCustomerSmsModal({ const [templatesLoading, setTemplatesLoading] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false) const [error, setError] = useState('') + const messageRef = useRef(null) useEffect(() => { if (open && target) { @@ -103,6 +106,21 @@ export function SendCustomerSmsModal({ if (tpl) setMessage(tpl.body.slice(0, MAX_LEN)) } + function insertVariable(token: string) { + if (selectedTemplate?.isVerified) return + const el = messageRef.current + const start = el?.selectionStart ?? message.length + const end = el?.selectionEnd ?? message.length + const next = `${message.slice(0, start)}${token}${message.slice(end)}`.slice(0, MAX_LEN) + const inserted = Math.min(token.length, MAX_LEN - message.slice(0, start).length) + const cursor = start + Math.max(0, inserted) + setMessage(next) + requestAnimationFrame(() => { + el?.focus() + el?.setSelectionRange(cursor, cursor) + }) + } + async function handleSubmit() { if (!target || !canSend) return setIsSubmitting(true) @@ -216,8 +234,31 @@ export function SendCustomerSmsModal({
+
+ {SMS_VARS.map((token) => ( + + ))} +