DispatchPage.vue: 1320→1217 lines - Extract SbModal.vue + SbContextMenu.vue reusable components - Extract useAbsenceResize composable - Extract dispatch constants to config/dispatch.js ProjectWizard.vue: 1185→673 lines (-43%) - Extract useWizardPublish composable (270-line publish function) - Extract useWizardCatalog composable - Extract wizard-constants.js (step labels, options, categories) SettingsPage.vue: 1172→850 lines (-27%) - Extract usePermissionMatrix composable - Extract useUserGroups composable - Extract useLegacySync composable ClientDetailPage.vue: 1169→864 lines (-26%) - Extract useClientData composable (loadCustomer broken into sub-functions) - Extract useEquipmentActions composable - Extract client-constants.js + erp-pdf.js utility checkout.js: 639→408 lines (-36%) - Extract address-search.js module - Extract otp.js module - Extract email-templates.js module - Extract project-templates.js module - Add erpQuery() helper to DRY repeated URL construction Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
52 lines
2.1 KiB
JavaScript
52 lines
2.1 KiB
JavaScript
'use strict'
|
|
const { httpRequest } = require('./helpers')
|
|
|
|
const SUPABASE_URL = 'https://rddrjzptzhypltuzmere.supabase.co'
|
|
const SUPABASE_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJkZHJqenB0emh5cGx0dXptZXJlIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzA4MTY4NTYsImV4cCI6MjA4NjM5Mjg1Nn0.EluFlKBze8BYM6AFx88G7kt21EvR18EI3uw1zgCXVzs'
|
|
|
|
function wordsToIlike (str) {
|
|
const words = str.split(/\s+/).filter(w => w.length >= 2)
|
|
if (!words.length) return ''
|
|
return '*' + words.map(w => encodeURIComponent(w)).join('*') + '*'
|
|
}
|
|
|
|
async function searchAddresses (term, limit = 8) {
|
|
const clean = term.trim()
|
|
if (clean.length < 3) return []
|
|
|
|
const numMatch = clean.match(/^\s*(\d+)\s*(.*)/)
|
|
const headers = { apikey: SUPABASE_KEY, Authorization: 'Bearer ' + SUPABASE_KEY }
|
|
const select = 'adresse_formatee,numero_municipal,numero_unite,code_postal,odonyme_recompose_normal,nom_municipalite,latitude,longitude,identifiant_unique_adresse'
|
|
const base = `${SUPABASE_URL}/rest/v1/addresses?select=${select}&limit=${limit}`
|
|
|
|
let results = []
|
|
|
|
if (numMatch) {
|
|
const num = numMatch[1]
|
|
const street = numMatch[2].trim()
|
|
let url = `${base}&numero_municipal=eq.${num}`
|
|
if (street) url += `&odonyme_recompose_normal=ilike.${wordsToIlike(street)}`
|
|
url += '&order=nom_municipalite'
|
|
const res = await httpRequest(url, '', { headers })
|
|
results = Array.isArray(res.data) ? res.data : []
|
|
|
|
if (!results.length && num.length >= 2) {
|
|
let url2 = `${base}&numero_municipal=like.${num}*`
|
|
if (street) url2 += `&odonyme_recompose_normal=ilike.${wordsToIlike(street)}`
|
|
url2 += '&order=nom_municipalite'
|
|
const res2 = await httpRequest(url2, '', { headers })
|
|
results = Array.isArray(res2.data) ? res2.data : []
|
|
}
|
|
} else {
|
|
const pattern = wordsToIlike(clean)
|
|
if (!pattern) return []
|
|
const url = `${base}&odonyme_recompose_normal=ilike.${pattern}&order=nom_municipalite`
|
|
const res = await httpRequest(url, '', { headers })
|
|
results = Array.isArray(res.data) ? res.data : []
|
|
}
|
|
|
|
return results.map(a => ({ ...a, fiber_available: false }))
|
|
}
|
|
|
|
module.exports = { searchAddresses, wordsToIlike }
|