chore: remove location templates

This commit is contained in:
Muhsin Keloth
2025-07-22 17:34:12 +04:00
parent 2357f6ae47
commit a0e2936ab3
4 changed files with 25 additions and 256 deletions
@@ -90,20 +90,7 @@ const processedStringWithVariableHighlight = computed(() => {
const rules = computed(() => {
const paramRules = {};
Object.keys(processedParams.value).forEach(key => {
if (
key === 'header' &&
processedParams.value.header.location_type === 'location'
) {
// Add specific validation for location parameters
paramRules[key] = {
location: {
latitude: { required: requiredIf(true) },
longitude: { required: requiredIf(true) },
},
};
} else {
paramRules[key] = { required: requiredIf(true) };
}
paramRules[key] = { required: requiredIf(true) };
});
return {
processedParams: paramRules,
@@ -170,20 +157,6 @@ const generateVariables = () => {
media_url: '',
media_type: headerComponent.value.format.toLowerCase(),
};
} else if (
headerComponent.value.format &&
headerComponent.value.format === 'LOCATION'
) {
// Location headers need location data
allVariables.header = {
location: {
latitude: '',
longitude: '',
name: '',
address: '',
},
location_type: 'location',
};
}
}
@@ -416,118 +389,25 @@ onMounted(() => {
'Header Parameters'
}}
</h4>
<!-- Location Parameters -->
<!-- Header Parameters -->
<div
v-if="processedParams.header.location_type === 'location'"
class="p-3 mb-4 space-y-3 w-full rounded-lg border bg-n-solid-1 border-n-weak"
v-for="[key] in Object.entries(processedParams.header)"
:key="`header-${key}`"
class="flex gap-2 items-center mb-2 w-full"
>
<div class="flex gap-2 items-center mb-2">
<div
class="flex justify-center items-center w-4 h-4 bg-blue-500 rounded-full"
>
<div class="w-2 h-2 bg-white rounded-full" />
</div>
<span class="text-sm font-medium text-n-slate-12">{{
t('WHATSAPP_TEMPLATES.PARSER.LOCATION_DETAILS')
}}</span>
</div>
<div class="grid grid-cols-2 gap-2">
<div>
<label class="block mb-1 text-xs font-medium text-n-slate-10">
{{ t('WHATSAPP_TEMPLATES.PARSER.LATITUDE') }}
<span class="text-red-500">*</span>
</label>
<Input
v-model="processedParams.header.location.latitude"
custom-input-class="!h-8 w-full !bg-transparent"
class="w-full"
type="number"
step="any"
placeholder="37.7749 (San Francisco)"
:message-type="getFieldErrorType('header.location.latitude')"
/>
<span class="text-xs text-n-slate-9">{{
t('WHATSAPP_TEMPLATES.PARSER.LATITUDE_RANGE')
}}</span>
</div>
<div>
<label class="block mb-1 text-xs font-medium text-n-slate-10">
{{ t('WHATSAPP_TEMPLATES.PARSER.LONGITUDE') }}
<span class="text-red-500">*</span>
</label>
<Input
v-model="processedParams.header.location.longitude"
custom-input-class="!h-8 w-full !bg-transparent"
class="w-full"
type="number"
step="any"
placeholder="-122.4194 (San Francisco)"
:message-type="getFieldErrorType('header.location.longitude')"
/>
<span class="text-xs text-n-slate-9">{{
t('WHATSAPP_TEMPLATES.PARSER.LONGITUDE_RANGE')
}}</span>
</div>
</div>
<div>
<label class="block mb-1 text-xs font-medium text-n-slate-10">
{{ t('WHATSAPP_TEMPLATES.PARSER.LOCATION_NAME') }}
</label>
<Input
v-model="processedParams.header.location.name"
custom-input-class="!h-8 w-full !bg-transparent"
class="w-full"
placeholder="Your Business Name"
:message-type="getFieldErrorType('header.location.name')"
/>
</div>
<div>
<label class="block mb-1 text-xs font-medium text-n-slate-10">
{{ t('WHATSAPP_TEMPLATES.PARSER.FULL_ADDRESS') }}
</label>
<Input
v-model="processedParams.header.location.address"
custom-input-class="!h-8 w-full !bg-transparent"
class="w-full"
placeholder="123 Main Street, City, State 12345"
:message-type="getFieldErrorType('header.location.address')"
/>
</div>
<div
class="p-2 text-xs bg-blue-50 rounded border-l-4 border-blue-400 text-n-slate-9"
<span
class="flex items-center h-8 text-sm min-w-6 ltr:text-left rtl:text-right text-n-slate-10"
>
<strong>{{ t('WHATSAPP_TEMPLATES.PARSER.TIP_LABEL') }}</strong>
{{ t('WHATSAPP_TEMPLATES.PARSER.LOCATION_TIP') }}
</div>
</div>
<!-- Regular Header Parameters -->
<div v-if="processedParams.header.location_type !== 'location'">
<div
v-for="[key] in Object.entries(processedParams.header).filter(
([k]) => !['location', 'location_type'].includes(k)
)"
:key="`header-${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"
>
{{ getHeaderFieldLabel(key) }}
</span>
<Input
v-model="processedParams.header[key]"
custom-input-class="!h-8 w-full !bg-transparent"
class="w-full"
:message-type="getFieldErrorType(`header.${key}`)"
:placeholder="getHeaderFieldPlaceholder(key)"
:type="key === 'media_url' ? 'url' : 'text'"
/>
</div>
{{ getHeaderFieldLabel(key) }}
</span>
<Input
v-model="processedParams.header[key]"
custom-input-class="!h-8 w-full !bg-transparent"
class="w-full"
:message-type="getFieldErrorType(`header.${key}`)"
:placeholder="getHeaderFieldPlaceholder(key)"
:type="key === 'media_url' ? 'url' : 'text'"
/>
</div>
</div>
@@ -35,12 +35,14 @@ export default {
return false;
}
// Filter out interactive templates (LIST, PRODUCT, CATALOG)
const hasInteractiveComponents = template.components.some(component =>
['LIST', 'PRODUCT', 'CATALOG'].includes(component.type)
// Filter out interactive templates (LIST, PRODUCT, CATALOG) and location templates
const hasUnsupportedComponents = template.components.some(
component =>
['LIST', 'PRODUCT', 'CATALOG'].includes(component.type) ||
(component.type === 'HEADER' && component.format === 'LOCATION')
);
if (hasInteractiveComponents) {
if (hasUnsupportedComponents) {
return false;
}
@@ -25,16 +25,7 @@
"VARIABLE_PLACEHOLDER": "Enter {variable} value",
"GO_BACK_LABEL": "Go Back",
"SEND_MESSAGE_LABEL": "Send Message",
"FORM_ERROR_MESSAGE": "Please fill all variables before sending",
"LOCATION_DETAILS": "Location Details",
"LATITUDE": "Latitude",
"LONGITUDE": "Longitude",
"LOCATION_NAME": "Location Name",
"FULL_ADDRESS": "Full Address",
"LATITUDE_RANGE": "Range: -90.0 to 90.0",
"LONGITUDE_RANGE": "Range: -180.0 to 180.0",
"LOCATION_TIP": "You can get coordinates by searching your location on Google Maps, right-clicking the pin, and copying the latitude/longitude values.",
"TIP_LABEL": "Tip:"
"FORM_ERROR_MESSAGE": "Please fill all variables before sending"
}
}
}
@@ -83,8 +83,6 @@ class Whatsapp::TemplateProcessorService
header_component = template['components'].find { |c| c['type'] == 'HEADER' }
if header_component&.dig('format')&.in?(%w[IMAGE VIDEO DOCUMENT])
process_media_template_params(template, header_component)
elsif header_component&.dig('format') == 'LOCATION'
process_location_template_params(template, header_component)
elsif template['category']&.downcase == 'authentication'
process_authentication_template_params(template)
else
@@ -124,35 +122,6 @@ class Whatsapp::TemplateProcessorService
@template_params = components
end
def process_location_template_params(_template, header_component)
# For templates with location headers
components = []
# Add location header component
# Location headers typically include latitude, longitude, name, and address
location_params = if template_params['processed_params'].is_a?(Hash) && template_params['processed_params']['header']
build_location_parameter(template_params['processed_params']['header'])
else
# Use example location if available, otherwise create placeholder
build_default_location_parameter(header_component)
end
if location_params
components << {
type: 'header',
parameters: [location_params]
}
end
# Add body parameters if any
if template_params['processed_params'].present? && !template_params['processed_params'].is_a?(Hash)
body_params = template_params['processed_params'].map { |_, value| { type: 'text', text: value } }
components << { type: 'body', parameters: body_params } if body_params.present?
end
@template_params = components
end
def process_authentication_template_params(_template)
# Authentication templates typically have OTP codes and expiration times
components = []
@@ -184,10 +153,7 @@ class Whatsapp::TemplateProcessorService
if key == 'media_url' && processed_params['header']['media_type'].present?
media_param = build_media_parameter(value, processed_params['header']['media_type'])
header_params << media_param if media_param
elsif key == 'location' && processed_params['header']['location_type'] == 'location'
location_param = build_location_parameter(value)
header_params << location_param if location_param
elsif %w[media_type location_type].exclude?(key)
elsif key != 'media_type'
header_params << build_parameter(value)
end
end
@@ -374,63 +340,6 @@ class Whatsapp::TemplateProcessorService
end
end
def build_location_parameter(location_data)
# Location parameter for header components
# Can be a hash with lat/lng or a string address
case location_data
when Hash
# Structured location data
validate_location_data(location_data)
{
type: 'location',
location: {
latitude: location_data['latitude'].to_f,
longitude: location_data['longitude'].to_f,
name: location_data['name'].to_s.strip,
address: location_data['address'].to_s.strip
}
}
when String
# Address string - parse or use as name
address = sanitize_parameter(location_data)
{
type: 'location',
location: {
latitude: 0.0,
longitude: 0.0,
name: address,
address: address
}
}
end
end
def build_default_location_parameter(header_component)
# Build default location from template example or placeholder
if header_component['example'] && header_component['example']['header_handle']
example_location = header_component['example']['header_handle'].first
{
type: 'location',
location: {
latitude: 37.7749,
longitude: -122.4194,
name: example_location || 'Business Location',
address: example_location || 'San Francisco, CA'
}
}
else
{
type: 'location',
location: {
latitude: 37.7749,
longitude: -122.4194,
name: 'Business Location',
address: 'San Francisco, CA'
}
}
end
end
def build_authentication_parameter(value, param_type)
# Authentication-specific parameters
sanitized_value = sanitize_parameter(value)
@@ -469,19 +378,6 @@ class Whatsapp::TemplateProcessorService
end
end
def validate_location_data(location_data)
required_fields = %w[latitude longitude]
missing_fields = required_fields.reject { |field| location_data.key?(field) }
raise ArgumentError, "Missing required location fields: #{missing_fields.join(', ')}" if missing_fields.any?
lat = location_data['latitude'].to_f
lng = location_data['longitude'].to_f
raise ArgumentError, 'Latitude must be between -90 and 90' unless lat.between?(-90, 90)
raise ArgumentError, 'Longitude must be between -180 and 180' unless lng.between?(-180, 180)
end
def validated_body_object(template)
# we don't care if its not approved template
return if template['status'] != 'approved'