first commit
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
// src/utils/dateBR.js
|
||||
|
||||
export function pad2(n) {
|
||||
return String(n).padStart(2, '0')
|
||||
}
|
||||
|
||||
// ISO (YYYY-MM-DD) -> BR (DD-MM-YYYY)
|
||||
export function isoToBR(iso) {
|
||||
if (!iso) return ''
|
||||
const s = String(iso).slice(0, 10)
|
||||
const [y, m, d] = s.split('-')
|
||||
if (!y || !m || !d) return ''
|
||||
return `${pad2(d)}-${pad2(m)}-${y}`
|
||||
}
|
||||
|
||||
// BR (DD-MM-YYYY) -> ISO (YYYY-MM-DD)
|
||||
export function brToISO(br) {
|
||||
if (!br) return null
|
||||
const s = String(br).trim()
|
||||
const m = s.match(/^(\d{2})-(\d{2})-(\d{4})$/)
|
||||
if (!m) return null
|
||||
const [, dd, mm, yyyy] = m
|
||||
return `${yyyy}-${mm}-${dd}`
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// src/utils/slotsGenerator.js
|
||||
|
||||
function toMinutes(hhmm) {
|
||||
const [h, m] = String(hhmm).slice(0, 5).split(':').map(Number)
|
||||
return (h * 60) + m
|
||||
}
|
||||
function toHHMM(min) {
|
||||
const h = Math.floor(min / 60)
|
||||
const m = min % 60
|
||||
return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Gera lista de horários (HH:MM) a partir:
|
||||
* - janelas: [{hora_inicio:'08:00', hora_fim:'12:00', ativo:true}]
|
||||
* - regra: {passo_minutos:60, offset_minutos:30, ativo:true}
|
||||
*
|
||||
* Retorna horários de INÍCIO (igual Altegio)
|
||||
*/
|
||||
export function gerarSlotsDoDia(janelas, regra) {
|
||||
const passo = Number(regra?.passo_minutos || 60)
|
||||
const offset = Number(regra?.offset_minutos || 0)
|
||||
|
||||
const ativos = (janelas || []).filter(j => j?.ativo !== false)
|
||||
|
||||
const out = []
|
||||
|
||||
for (const j of ativos) {
|
||||
const start = toMinutes(j.hora_inicio)
|
||||
const end = toMinutes(j.hora_fim)
|
||||
|
||||
// encontra o primeiro t >= start que respeita offset
|
||||
// condição: t % passo == offset (mod passo), mas offset é dentro da hora.
|
||||
// Implementação simples: alinhar pelo minuto do dia:
|
||||
// alvo: t ≡ offset (mod passo) quando offset é interpretado no ciclo do passo.
|
||||
// Para seu uso (passo 60, offset 30), funciona perfeito.
|
||||
let t = start
|
||||
const mod = ((t % passo) + passo) % passo
|
||||
const need = ((offset - mod) + passo) % passo
|
||||
t = t + need
|
||||
|
||||
while (t + 1 <= end) {
|
||||
// só inclui se dentro do intervalo
|
||||
if (t >= start && t < end) out.push(toHHMM(t))
|
||||
t += passo
|
||||
}
|
||||
}
|
||||
|
||||
// unique + sort
|
||||
return Array.from(new Set(out)).sort()
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// src/utils/upgradeContext.js
|
||||
|
||||
/**
|
||||
* Parse "missing" query param into array of unique feature keys.
|
||||
* Accepts:
|
||||
* - "feature_a"
|
||||
* - "feature_a,feature_b"
|
||||
* - ["feature_a", "feature_b"] (vue-router pode entregar array)
|
||||
*/
|
||||
export function parseMissingKeys (missing) {
|
||||
if (!missing) return []
|
||||
|
||||
const raw = Array.isArray(missing) ? missing.join(',') : String(missing)
|
||||
const keys = raw
|
||||
.split(',')
|
||||
.map(s => s.trim())
|
||||
.filter(Boolean)
|
||||
|
||||
// unique preserving order
|
||||
const seen = new Set()
|
||||
const unique = []
|
||||
for (const k of keys) {
|
||||
if (!seen.has(k)) {
|
||||
seen.add(k)
|
||||
unique.push(k)
|
||||
}
|
||||
}
|
||||
return unique
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse redirect param. Only allow internal app paths to avoid open-redirect.
|
||||
* - Must start with "/"
|
||||
* - Must NOT start with "//"
|
||||
*/
|
||||
export function parseRedirectTo (redirect) {
|
||||
if (!redirect) return null
|
||||
const s = Array.isArray(redirect) ? redirect[0] : String(redirect)
|
||||
const trimmed = s.trim()
|
||||
if (!trimmed) return null
|
||||
if (!trimmed.startsWith('/')) return null
|
||||
if (trimmed.startsWith('//')) return null
|
||||
return trimmed
|
||||
}
|
||||
|
||||
/**
|
||||
* Build /upgrade URL with missing feature and redirect target.
|
||||
*/
|
||||
export function buildUpgradeUrl ({ missingKeys = [], redirectTo = null } = {}) {
|
||||
const keys = Array.isArray(missingKeys) ? missingKeys.filter(Boolean) : []
|
||||
const q = new URLSearchParams()
|
||||
|
||||
if (keys.length) q.set('missing', keys.join(','))
|
||||
if (redirectTo) q.set('redirect', redirectTo)
|
||||
|
||||
const qs = q.toString()
|
||||
return qs ? `/upgrade?${qs}` : '/upgrade'
|
||||
}
|
||||
Reference in New Issue
Block a user