chore: fix copy otp
This commit is contained in:
+14
-267
@@ -47,22 +47,6 @@ const footerComponent = computed(() => {
|
||||
);
|
||||
});
|
||||
|
||||
const buttonComponents = computed(() => {
|
||||
return templateComponents.value.filter(
|
||||
component => component.type === 'BUTTONS'
|
||||
);
|
||||
});
|
||||
|
||||
const legacyParams = computed(() => {
|
||||
const params = {};
|
||||
Object.keys(processedParams.value).forEach(key => {
|
||||
if (!['header', 'body', 'footer', 'buttons'].includes(key)) {
|
||||
params[key] = processedParams.value[key];
|
||||
}
|
||||
});
|
||||
return params;
|
||||
});
|
||||
|
||||
const processVariable = str => {
|
||||
return str.replace(/{{|}}/g, '');
|
||||
};
|
||||
@@ -113,26 +97,7 @@ const generateVariables = () => {
|
||||
allVariables.body = {};
|
||||
bodyVars.forEach(variable => {
|
||||
const key = processVariable(variable);
|
||||
// Special handling for authentication templates
|
||||
if (props.template?.category === 'AUTHENTICATION') {
|
||||
if (
|
||||
key === '1' ||
|
||||
key.toLowerCase().includes('otp') ||
|
||||
key.toLowerCase().includes('code')
|
||||
) {
|
||||
allVariables.body.otp_code = '';
|
||||
} else if (
|
||||
key === '2' ||
|
||||
key.toLowerCase().includes('expiry') ||
|
||||
key.toLowerCase().includes('minute')
|
||||
) {
|
||||
allVariables.body.expiry_minutes = '';
|
||||
} else {
|
||||
allVariables.body[key] = '';
|
||||
}
|
||||
} else {
|
||||
allVariables.body[key] = '';
|
||||
}
|
||||
allVariables.body[key] = '';
|
||||
});
|
||||
}
|
||||
|
||||
@@ -172,64 +137,9 @@ const generateVariables = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// Process button variables
|
||||
buttonComponents.value.forEach(buttonComponent => {
|
||||
if (buttonComponent.buttons) {
|
||||
buttonComponent.buttons.forEach((button, index) => {
|
||||
// Handle URL buttons with variables
|
||||
if (button.type === 'URL' && button.url && button.url.includes('{{')) {
|
||||
const buttonVars = button.url.match(/{{([^}]+)}}/g) || [];
|
||||
if (buttonVars.length > 0) {
|
||||
if (!allVariables.buttons) allVariables.buttons = [];
|
||||
allVariables.buttons[index] = {
|
||||
type: 'url',
|
||||
parameter: '',
|
||||
url: button.url,
|
||||
variables: buttonVars.map(v => processVariable(v)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Handle copy code buttons
|
||||
if (button.type === 'COPY_CODE') {
|
||||
if (!allVariables.buttons) allVariables.buttons = [];
|
||||
allVariables.buttons[index] = {
|
||||
type: 'copy_code',
|
||||
parameter: '',
|
||||
};
|
||||
}
|
||||
|
||||
// Handle interactive buttons with dynamic text
|
||||
if (['QUICK_REPLY', 'URL', 'PHONE_NUMBER'].includes(button.type)) {
|
||||
if (button.text && button.text.includes('{{')) {
|
||||
if (!allVariables.buttons) allVariables.buttons = [];
|
||||
allVariables.buttons[index] = {
|
||||
type: button.type.toLowerCase(),
|
||||
parameter: '',
|
||||
text: button.text,
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
processedParams.value = allVariables;
|
||||
};
|
||||
|
||||
const validateButtonParameter = (button, index) => {
|
||||
const parameter = processedParams.value.buttons[index].parameter;
|
||||
|
||||
if (button.type === 'copy_code') {
|
||||
if (parameter && parameter.length > 15) {
|
||||
processedParams.value.buttons[index].parameter = parameter.substring(
|
||||
0,
|
||||
15
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getHeaderFieldLabel = key => {
|
||||
if (key === 'media_url') {
|
||||
const mediaType = processedParams.value.header?.media_type || 'media';
|
||||
@@ -268,88 +178,10 @@ const getHeaderFieldPlaceholder = key => {
|
||||
return `Enter ${key} value`;
|
||||
};
|
||||
|
||||
const getBodyParameterLabel = key => {
|
||||
if (props.template?.category === 'AUTHENTICATION') {
|
||||
switch (key) {
|
||||
case 'otp_code':
|
||||
return t('WHATSAPP_TEMPLATES.PARSER.OTP_CODE') || 'OTP Code';
|
||||
case 'expiry_minutes':
|
||||
return (
|
||||
t('WHATSAPP_TEMPLATES.PARSER.EXPIRY_MINUTES') || 'Expiry (minutes)'
|
||||
);
|
||||
default:
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return key;
|
||||
};
|
||||
|
||||
const getBodyParameterPlaceholder = key => {
|
||||
if (props.template?.category === 'AUTHENTICATION') {
|
||||
switch (key) {
|
||||
case 'otp_code':
|
||||
return (
|
||||
t('WHATSAPP_TEMPLATES.PARSER.OTP_CODE_PLACEHOLDER') ||
|
||||
'Enter 4-8 digit OTP code'
|
||||
);
|
||||
case 'expiry_minutes':
|
||||
return (
|
||||
t('WHATSAPP_TEMPLATES.PARSER.EXPIRY_MINUTES_PLACEHOLDER') ||
|
||||
'Enter expiry time in minutes'
|
||||
);
|
||||
default:
|
||||
return `Enter ${key} value`;
|
||||
}
|
||||
}
|
||||
return `Enter ${key} value`;
|
||||
};
|
||||
|
||||
const getBodyParameterType = key => {
|
||||
if (props.template?.category === 'AUTHENTICATION') {
|
||||
switch (key) {
|
||||
case 'otp_code':
|
||||
return 'tel';
|
||||
case 'expiry_minutes':
|
||||
return 'number';
|
||||
default:
|
||||
return 'text';
|
||||
}
|
||||
}
|
||||
return 'text';
|
||||
};
|
||||
|
||||
const getBodyParameterMaxLength = key => {
|
||||
if (props.template?.category === 'AUTHENTICATION') {
|
||||
switch (key) {
|
||||
case 'otp_code':
|
||||
return 8;
|
||||
case 'expiry_minutes':
|
||||
return 3;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const sendMessage = async () => {
|
||||
const isValid = await v$.value.$validate();
|
||||
if (!isValid) return;
|
||||
|
||||
// Auto-populate button parameters for authentication templates
|
||||
const finalParams = { ...processedParams.value };
|
||||
if (props.template?.category === 'AUTHENTICATION' && finalParams.buttons) {
|
||||
finalParams.buttons.forEach((button, index) => {
|
||||
if (
|
||||
button.type === 'url' &&
|
||||
button.variables?.includes('1') &&
|
||||
finalParams.body?.otp_code
|
||||
) {
|
||||
finalParams.buttons[index].parameter = finalParams.body.otp_code;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const payload = {
|
||||
message: processedString.value,
|
||||
templateParams: {
|
||||
@@ -357,7 +189,7 @@ const sendMessage = async () => {
|
||||
category: props.template.category,
|
||||
language: props.template.language,
|
||||
namespace: props.template.namespace,
|
||||
processed_params: finalParams,
|
||||
processed_params: processedParams.value,
|
||||
},
|
||||
};
|
||||
emit('sendMessage', payload);
|
||||
@@ -427,103 +259,9 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Body Variables -->
|
||||
<div v-if="processedParams.body" class="w-full">
|
||||
<h4 class="mb-2 text-sm font-medium text-n-slate-12">
|
||||
{{
|
||||
t('WHATSAPP_TEMPLATES.PARSER.BODY_PARAMETERS') || 'Body Parameters'
|
||||
}}
|
||||
</h4>
|
||||
<div
|
||||
v-for="(variable, key) in processedParams.body"
|
||||
:key="`body-${key}`"
|
||||
class="flex gap-2 items-center mb-2 w-full"
|
||||
>
|
||||
<span
|
||||
class="flex items-center h-8 text-sm min-w-6 ltr:text-left rtl:text-right text-n-slate-10"
|
||||
>
|
||||
{{ getBodyParameterLabel(key) }}
|
||||
</span>
|
||||
<Input
|
||||
v-model="processedParams.body[key]"
|
||||
custom-input-class="!h-8 w-full !bg-transparent"
|
||||
class="w-full"
|
||||
:message-type="getFieldErrorType(`body.${key}`)"
|
||||
:placeholder="getBodyParameterPlaceholder(key)"
|
||||
:type="getBodyParameterType(key)"
|
||||
:maxlength="getBodyParameterMaxLength(key)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer Variables -->
|
||||
<div v-if="processedParams.footer" class="w-full">
|
||||
<h4 class="mb-2 text-sm font-medium text-n-slate-12">
|
||||
{{
|
||||
t('WHATSAPP_TEMPLATES.PARSER.FOOTER_PARAMETERS') ||
|
||||
'Footer Parameters'
|
||||
}}
|
||||
</h4>
|
||||
<div
|
||||
v-for="(variable, key) in processedParams.footer"
|
||||
:key="`footer-${key}`"
|
||||
class="flex gap-2 items-center mb-2 w-full"
|
||||
>
|
||||
<span
|
||||
class="flex items-center h-8 text-sm min-w-6 ltr:text-left rtl:text-right text-n-slate-10"
|
||||
>
|
||||
{{ key }}
|
||||
</span>
|
||||
<Input
|
||||
v-model="processedParams.footer[key]"
|
||||
custom-input-class="!h-8 w-full !bg-transparent"
|
||||
class="w-full"
|
||||
:message-type="getFieldErrorType(`footer.${key}`)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Button Variables -->
|
||||
<div v-if="processedParams.buttons" class="w-full">
|
||||
<h4 class="mb-2 text-sm font-medium text-n-slate-12">
|
||||
{{
|
||||
t('WHATSAPP_TEMPLATES.PARSER.BUTTON_PARAMETERS') ||
|
||||
'Button Parameters'
|
||||
}}
|
||||
</h4>
|
||||
<div
|
||||
v-for="(button, index) in processedParams.buttons"
|
||||
:key="`button-${index}`"
|
||||
class="flex gap-2 items-center mb-2 w-full"
|
||||
>
|
||||
<span
|
||||
class="flex items-center h-8 text-sm min-w-6 ltr:text-left rtl:text-right text-n-slate-10"
|
||||
>
|
||||
{{
|
||||
button.type === 'copy_code'
|
||||
? t('WHATSAPP_TEMPLATES.PARSER.COUPON_CODE') || 'Coupon Code'
|
||||
: `${t('WHATSAPP_TEMPLATES.PARSER.BUTTON') || 'Button'} ${index + 1}`
|
||||
}}
|
||||
</span>
|
||||
<Input
|
||||
v-model="processedParams.buttons[index].parameter"
|
||||
custom-input-class="!h-8 w-full !bg-transparent"
|
||||
class="w-full"
|
||||
:message-type="getFieldErrorType(`buttons.${index}.parameter`)"
|
||||
:placeholder="
|
||||
button.type === 'copy_code'
|
||||
? 'Enter coupon code (max 15 chars)'
|
||||
: 'Enter button parameter'
|
||||
"
|
||||
:max-length="button.type === 'copy_code' ? 15 : 500"
|
||||
@input="validateButtonParameter(button, index)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Legacy Variables (for backward compatibility) -->
|
||||
<!-- Variables -->
|
||||
<div
|
||||
v-for="(variable, key) in legacyParams"
|
||||
v-for="(variable, key) in processedParams.body || processedParams"
|
||||
:key="key"
|
||||
class="flex gap-2 items-center w-full"
|
||||
>
|
||||
@@ -533,10 +271,19 @@ onMounted(() => {
|
||||
{{ key }}
|
||||
</span>
|
||||
<Input
|
||||
v-model="processedParams[key]"
|
||||
:model-value="
|
||||
processedParams.body
|
||||
? processedParams.body[key]
|
||||
: processedParams[key]
|
||||
"
|
||||
custom-input-class="!h-8 w-full !bg-transparent"
|
||||
class="w-full"
|
||||
:message-type="getFieldErrorType(key)"
|
||||
@update:model-value="
|
||||
processedParams.body
|
||||
? (processedParams.body[key] = $event)
|
||||
: (processedParams[key] = $event)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
+188
-63
@@ -79,23 +79,84 @@ export default {
|
||||
);
|
||||
|
||||
const generateVariables = () => {
|
||||
const params = {};
|
||||
const allVariables = {};
|
||||
|
||||
// Add media URL field if template has media header
|
||||
if (hasMediaHeader.value) {
|
||||
params.media_url = '';
|
||||
}
|
||||
|
||||
// Add body variables
|
||||
// Process body variables
|
||||
const matchedVariables = templateString.value.match(/{{([^}]+)}}/g);
|
||||
if (matchedVariables) {
|
||||
const finalVars = matchedVariables.map(i => processVariable(i));
|
||||
finalVars.forEach(variable => {
|
||||
params[variable] = '';
|
||||
allVariables.body = {};
|
||||
matchedVariables.forEach(variable => {
|
||||
const key = processVariable(variable);
|
||||
// Special handling for authentication templates
|
||||
if (props.template?.category === 'AUTHENTICATION') {
|
||||
if (
|
||||
key === '1' ||
|
||||
key.toLowerCase().includes('otp') ||
|
||||
key.toLowerCase().includes('code')
|
||||
) {
|
||||
allVariables.body.otp_code = '';
|
||||
} else if (
|
||||
key === '2' ||
|
||||
key.toLowerCase().includes('expiry') ||
|
||||
key.toLowerCase().includes('minute')
|
||||
) {
|
||||
allVariables.body.expiry_minutes = '';
|
||||
} else {
|
||||
allVariables.body[key] = '';
|
||||
}
|
||||
} else {
|
||||
allVariables.body[key] = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
processedParams.value = params;
|
||||
// Add media URL field if template has media header
|
||||
if (hasMediaHeader.value) {
|
||||
if (!allVariables.header) allVariables.header = {};
|
||||
allVariables.header.media_url = '';
|
||||
allVariables.header.media_type =
|
||||
headerComponent.value.format.toLowerCase();
|
||||
}
|
||||
|
||||
// Process button variables
|
||||
const buttonComponents = props.template.components.filter(
|
||||
component => component.type === 'BUTTONS'
|
||||
);
|
||||
|
||||
buttonComponents.forEach(buttonComponent => {
|
||||
if (buttonComponent.buttons) {
|
||||
buttonComponent.buttons.forEach((button, index) => {
|
||||
// Handle URL buttons with variables
|
||||
if (
|
||||
button.type === 'URL' &&
|
||||
button.url &&
|
||||
button.url.includes('{{')
|
||||
) {
|
||||
const buttonVars = button.url.match(/{{([^}]+)}}/g) || [];
|
||||
if (buttonVars.length > 0) {
|
||||
if (!allVariables.buttons) allVariables.buttons = [];
|
||||
allVariables.buttons[index] = {
|
||||
type: 'url',
|
||||
parameter: '',
|
||||
url: button.url,
|
||||
variables: buttonVars.map(v => processVariable(v)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Handle copy code buttons
|
||||
if (button.type === 'COPY_CODE') {
|
||||
if (!allVariables.buttons) allVariables.buttons = [];
|
||||
allVariables.buttons[index] = {
|
||||
type: 'copy_code',
|
||||
parameter: '',
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
processedParams.value = allVariables;
|
||||
};
|
||||
|
||||
const resetTemplate = () => {
|
||||
@@ -106,27 +167,22 @@ export default {
|
||||
v$.value.$touch();
|
||||
if (v$.value.$invalid) return;
|
||||
|
||||
// Prepare enhanced template parameters for media support
|
||||
const enhancedParams = {};
|
||||
|
||||
// Handle media header
|
||||
if (hasMediaHeader.value && processedParams.value.media_url) {
|
||||
enhancedParams.header = {
|
||||
media_url: processedParams.value.media_url,
|
||||
media_type: headerComponent.value.format.toLowerCase(),
|
||||
};
|
||||
}
|
||||
|
||||
// Handle body variables
|
||||
const bodyParams = {};
|
||||
Object.keys(processedParams.value).forEach(key => {
|
||||
if (key !== 'media_url') {
|
||||
bodyParams[key] = processedParams.value[key];
|
||||
}
|
||||
});
|
||||
|
||||
if (Object.keys(bodyParams).length > 0) {
|
||||
enhancedParams.body = bodyParams;
|
||||
// Auto-populate button parameters for authentication templates
|
||||
const finalParams = { ...processedParams.value };
|
||||
if (
|
||||
props.template?.category === 'AUTHENTICATION' &&
|
||||
finalParams.buttons
|
||||
) {
|
||||
finalParams.buttons.forEach((button, index) => {
|
||||
if (button.type === 'url') {
|
||||
// For authentication templates, auto-populate URL button parameter with OTP
|
||||
if (finalParams.body?.['1']) {
|
||||
finalParams.buttons[index].parameter = finalParams.body['1'];
|
||||
} else if (finalParams.body?.otp_code) {
|
||||
finalParams.buttons[index].parameter = finalParams.body.otp_code;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const payload = {
|
||||
@@ -136,7 +192,7 @@ export default {
|
||||
category: props.template.category,
|
||||
language: props.template.language,
|
||||
namespace: props.template.namespace,
|
||||
processed_params: enhancedParams,
|
||||
processed_params: finalParams,
|
||||
},
|
||||
};
|
||||
emit('sendMessage', payload);
|
||||
@@ -170,63 +226,132 @@ export default {
|
||||
<div v-if="variables || hasMediaHeader" class="p-2.5">
|
||||
<!-- Media Header Section -->
|
||||
<div v-if="hasMediaHeader" class="mb-4">
|
||||
<p class="text-sm font-semibold mb-2.5">
|
||||
<p class="mb-2.5 text-sm font-semibold">
|
||||
{{
|
||||
headerComponent.format.charAt(0) +
|
||||
headerComponent.format.slice(1).toLowerCase()
|
||||
$t('WHATSAPP_TEMPLATES.PARSER.MEDIA_HEADER_LABEL', {
|
||||
type:
|
||||
headerComponent.format.charAt(0) +
|
||||
headerComponent.format.slice(1).toLowerCase(),
|
||||
}) ||
|
||||
`${
|
||||
headerComponent.format.charAt(0) +
|
||||
headerComponent.format.slice(1).toLowerCase()
|
||||
} Header`
|
||||
}}
|
||||
Header
|
||||
</p>
|
||||
<div class="items-center flex mb-2.5">
|
||||
<div class="flex items-center mb-2.5">
|
||||
<span
|
||||
class="bg-n-alpha-black2 text-n-slate-12 inline-block rounded-md text-xs py-2.5 px-6"
|
||||
class="inline-block px-6 py-2.5 text-xs rounded-md bg-n-alpha-black2 text-n-slate-12"
|
||||
>
|
||||
{{ headerComponent.format.toLowerCase() }} URL
|
||||
{{
|
||||
$t('WHATSAPP_TEMPLATES.PARSER.MEDIA_URL_LABEL', {
|
||||
type: headerComponent.format.toLowerCase(),
|
||||
}) || `${headerComponent.format.toLowerCase()} URL`
|
||||
}}
|
||||
</span>
|
||||
<woot-input
|
||||
v-model="processedParams.media_url"
|
||||
type="url"
|
||||
class="flex-1 text-sm ml-2.5"
|
||||
class="flex-1 ml-2.5 text-sm"
|
||||
:placeholder="`Enter ${headerComponent.format.toLowerCase()} URL`"
|
||||
:styles="{ marginBottom: 0 }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Variables Section -->
|
||||
<div v-if="variables">
|
||||
<p class="text-sm font-semibold mb-2.5">
|
||||
<!-- Body Variables Section -->
|
||||
<div v-if="processedParams.body">
|
||||
<p class="mb-2.5 text-sm font-semibold">
|
||||
{{ $t('WHATSAPP_TEMPLATES.PARSER.VARIABLES_LABEL') }}
|
||||
</p>
|
||||
<div
|
||||
v-for="(variable, key) in processedParams"
|
||||
:key="key"
|
||||
class="items-center flex mb-2.5"
|
||||
v-for="(variable, key) in processedParams.body"
|
||||
:key="`body-${key}`"
|
||||
class="flex items-center mb-2.5"
|
||||
>
|
||||
<!-- Skip media_url as it's handled above -->
|
||||
<template v-if="key !== 'media_url'">
|
||||
<span
|
||||
class="bg-n-alpha-black2 text-n-slate-12 inline-block rounded-md text-xs py-2.5 px-6"
|
||||
>
|
||||
{{ key }}
|
||||
</span>
|
||||
<woot-input
|
||||
v-model="processedParams[key]"
|
||||
type="text"
|
||||
class="flex-1 text-sm ml-2.5"
|
||||
:styles="{ marginBottom: 0 }"
|
||||
/>
|
||||
</template>
|
||||
<span
|
||||
class="inline-block px-6 py-2.5 text-xs rounded-md bg-n-alpha-black2 text-n-slate-12"
|
||||
>
|
||||
{{
|
||||
key === 'otp_code'
|
||||
? $t('WHATSAPP_TEMPLATES.PARSER.OTP_CODE') || 'OTP Code'
|
||||
: key === 'expiry_minutes'
|
||||
? $t('WHATSAPP_TEMPLATES.PARSER.EXPIRY_MINUTES') ||
|
||||
'Expiry (minutes)'
|
||||
: key
|
||||
}}
|
||||
</span>
|
||||
<woot-input
|
||||
v-model="processedParams.body[key]"
|
||||
:type="
|
||||
key === 'otp_code'
|
||||
? 'tel'
|
||||
: key === 'expiry_minutes'
|
||||
? 'number'
|
||||
: 'text'
|
||||
"
|
||||
:maxlength="
|
||||
key === 'otp_code' ? 8 : key === 'expiry_minutes' ? 3 : null
|
||||
"
|
||||
:placeholder="
|
||||
key === 'otp_code'
|
||||
? 'Enter 4-8 digit OTP'
|
||||
: key === 'expiry_minutes'
|
||||
? 'Enter expiry minutes'
|
||||
: `Enter ${key} value`
|
||||
"
|
||||
class="flex-1 ml-2.5 text-sm"
|
||||
:styles="{ marginBottom: 0 }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Button Variables Section -->
|
||||
<div v-if="processedParams.buttons">
|
||||
<p class="mb-2.5 text-sm font-semibold">
|
||||
{{
|
||||
$t('WHATSAPP_TEMPLATES.PARSER.BUTTON_PARAMETERS') ||
|
||||
'Button Parameters'
|
||||
}}
|
||||
</p>
|
||||
<div
|
||||
v-for="(button, index) in processedParams.buttons"
|
||||
:key="`button-${index}`"
|
||||
class="flex items-center mb-2.5"
|
||||
>
|
||||
<span
|
||||
class="inline-block px-6 py-2.5 text-xs rounded-md bg-n-alpha-black2 text-n-slate-12"
|
||||
>
|
||||
{{
|
||||
button.type === 'copy_code'
|
||||
? $t('WHATSAPP_TEMPLATES.PARSER.COUPON_CODE') || 'Coupon Code'
|
||||
: $t('WHATSAPP_TEMPLATES.PARSER.BUTTON_LABEL', {
|
||||
index: index + 1,
|
||||
}) || `Button ${index + 1}`
|
||||
}}
|
||||
</span>
|
||||
<woot-input
|
||||
v-model="processedParams.buttons[index].parameter"
|
||||
:type="button.type === 'copy_code' ? 'text' : 'text'"
|
||||
:maxlength="button.type === 'copy_code' ? 15 : 500"
|
||||
:placeholder="
|
||||
button.type === 'copy_code'
|
||||
? 'Enter coupon code (max 15 chars)'
|
||||
: 'Enter button parameter'
|
||||
"
|
||||
class="flex-1 ml-2.5 text-sm"
|
||||
:styles="{ marginBottom: 0 }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
v-if="v$.$dirty && v$.$invalid"
|
||||
class="bg-n-ruby-9/20 rounded-md text-n-ruby-9 p-2.5 text-center"
|
||||
class="p-2.5 text-center rounded-md bg-n-ruby-9/20 text-n-ruby-9"
|
||||
>
|
||||
{{ $t('WHATSAPP_TEMPLATES.PARSER.FORM_ERROR_MESSAGE') }}
|
||||
</p>
|
||||
</div>
|
||||
<footer class="flex justify-end gap-2">
|
||||
<footer class="flex gap-2 justify-end">
|
||||
<NextButton
|
||||
faded
|
||||
slate
|
||||
|
||||
Reference in New Issue
Block a user