Skip to main content
The Utils module provides pure, stateless utility functions used throughout Estudo Organizado.

ID Generation

uid

Generate a unique identifier.
import { uid } from './utils.js';

const eventId = 'ev_' + uid();
const discId = 'disc_' + uid();
// Example: 'ev_l7k2m3n4p5q6r7s'
return
string
Unique string combining timestamp and random characters
The ID format is: timestamp_base36 + random_base36. While not guaranteed to be globally unique, collision probability is extremely low for typical use cases.

String Utilities

esc

Escape HTML entities for safe rendering.
import { esc } from './utils.js';

const userInput = '<script>alert("xss")</script>';
const safe = esc(userInput);
// Returns: '&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;'

el.innerHTML = `<div>${esc(evento.titulo)}</div>`;
str
string|number
String to escape (or any value that can be converted to string)
return
string
HTML-safe string with escaped entities
Escapes these characters:
  • &&amp;
  • <&lt;
  • >&gt;
  • "&quot;
  • '&#39;
Always use esc() when inserting user-generated content into innerHTML to prevent XSS attacks.

Date Utilities

getLocalDateStr

Convert a Date object to local date string in ISO format.
import { getLocalDateStr } from './utils.js';

const today = getLocalDateStr();
// Returns: '2026-03-03'

const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
const tomorrowStr = getLocalDateStr(tomorrow);
// Returns: '2026-03-04'
dateObj
Date
default:"new Date()"
Date object to convert (defaults to current date/time)
return
string
Date string in ‘YYYY-MM-DD’ format, adjusted for local timezone
This function accounts for timezone offset, ensuring dates are consistent with the user’s local time rather than UTC.

todayStr

Get today’s date string (cached for performance).
import { todayStr } from './utils.js';

const today = todayStr();
// Returns: '2026-03-03'

if (evento.data === todayStr()) {
  console.log('Event is today!');
}
return
string
Today’s date in ‘YYYY-MM-DD’ format
The result is cached in _todayCache. Call invalidateTodayCache() if the app runs across midnight (rare in single-session usage).

invalidateTodayCache

Clear the today date cache.
import { invalidateTodayCache } from './utils.js';

// Typically called on app resume or after long idle:
invalidateTodayCache();

formatDate

Format a date string for display in Brazilian Portuguese.
import { formatDate } from './utils.js';

const formatted = formatDate('2026-03-03');
// Returns: '03/03/2026'

const display = formatDate(evento.data);
str
string
required
Date string in ‘YYYY-MM-DD’ format
return
string
Formatted date in ‘DD/MM/YYYY’ format

cutoffDateStr

Calculate a date N days in the past.
import { cutoffDateStr } from './utils.js';

const sevenDaysAgo = cutoffDateStr(7);
const thirtyDaysAgo = cutoffDateStr(30);

// Filter recent events:
const recentEvents = state.eventos.filter(e => 
  e.data >= cutoffDateStr(7)
);
days
number
required
Number of days to go back from today
return
string
Date string in ‘YYYY-MM-DD’ format

Time Utilities

formatTime

Format seconds as HH:MM:SS or MM:SS.
import { formatTime } from './utils.js';

formatTime(45);      // Returns: '00:45'
formatTime(3665);    // Returns: '01:01:05'
formatTime(0);       // Returns: '00:00'
seconds
number
required
Total seconds to format
return
string
Formatted time string (MM:SS if less than 1 hour, HH:MM:SS otherwise)

pad

Pad a number with leading zero.
import { pad } from './utils.js';

pad(5);   // Returns: '05'
pad(12);  // Returns: '12'
pad(0);   // Returns: '00'
n
number
required
Number to pad
return
string
Two-character string with leading zero if needed

Event Utilities

getEventStatus

Determine the status of an event based on its date and status field.
import { getEventStatus } from './utils.js';

const evento = {
  data: '2026-03-01',
  status: 'agendado'
};

const status = getEventStatus(evento);
// Returns: 'atrasado' (because date is before today)
evento
object
required
Event object with status and data fields
return
string
Event status: 'estudei', 'atrasado', or 'agendado'
Logic:
  1. If evento.status === 'estudei' → return 'estudei'
  2. If evento.data < todayStr() → return 'atrasado'
  3. Otherwise → return 'agendado'

Habit Types

HABIT_TYPES

Array of study habit definitions.
import { HABIT_TYPES } from './utils.js';

HABIT_TYPES.forEach(habit => {
  console.log(habit.label, habit.icon, habit.color);
});
HABIT_TYPES
array
Array of habit type objects
Each habit object contains:
key
string
Unique identifier (e.g., ‘questoes’, ‘revisao’)
label
string
Display name (e.g., ‘Questões’, ‘Revisão’)
icon
string
Emoji icon (e.g., ’📝’, ’🔄’)
color
string
Hex color code (e.g., ‘#3b82f6’)

Available Habit Types

KeyLabelIconColor
questoesQuestões📝#3b82f6 (blue)
revisaoRevisão🔄#10b981 (green)
discursivaDiscursiva✍️#f59e0b (amber)
simuladoSimulado🎯#ef4444 (red)
leituraLeitura Seca📖#8b5cf6 (purple)
informativoInformativos📰#06b6d4 (cyan)
sumulaSúmulas⚖️#6366f1 (indigo)
videoaulaVideoaula📺#ec4899 (pink)

getHabitType

Get a habit type definition by key.
import { getHabitType } from './utils.js';

const questoes = getHabitType('questoes');
console.log(questoes.label);  // 'Questões'
console.log(questoes.icon);   // '📝'
console.log(questoes.color);  // '#3b82f6'

const unknown = getHabitType('invalid');
// Returns: undefined
key
string
required
Habit type key
return
object|undefined
Habit type object or undefined if not found

Usage Examples

Date Range Filtering

import { todayStr, cutoffDateStr } from './utils.js';
import { state } from './store.js';

const today = todayStr();
const weekAgo = cutoffDateStr(7);

const thisWeekEvents = state.eventos.filter(e => 
  e.data >= weekAgo && e.data <= today
);

Safe HTML Rendering

import { esc } from './utils.js';

function renderEventTitle(evento) {
  return `
    <div class="event-title">
      ${esc(evento.titulo)}
    </div>
  `;
}

Time Display

import { formatTime, getElapsedSeconds } from './utils.js';
import { state } from './store.js';

const evento = state.eventos[0];
const elapsed = getElapsedSeconds(evento);
const display = formatTime(elapsed);

console.log(`Studied for ${display}`);
// Output: 'Studied for 01:23:45'

Habit Icon Display

import { getHabitType } from './utils.js';

function renderHabitBadge(habitKey) {
  const habit = getHabitType(habitKey);
  if (!habit) return '';
  
  return `
    <span style="color: ${habit.color}">
      ${habit.icon} ${habit.label}
    </span>
  `;
}

renderHabitBadge('questoes');
// Returns: '<span style="color: #3b82f6">📝 Questões</span>'

Unique ID Generation

import { uid } from './utils.js';
import { state, scheduleSave } from './store.js';

const newEvent = {
  id: 'ev_' + uid(),
  titulo: 'Study Session',
  data: todayStr(),
  duracao: 60,
  status: 'agendado',
  tempoAcumulado: 0,
  criadoEm: new Date().toISOString()
};

state.eventos.push(newEvent);
scheduleSave();

Performance Notes

  • todayStr() is cached and only computed once per session for performance
  • esc() is called frequently, so it’s kept minimal (no regex, just string replacement)
  • getHabitType() uses Array.find() which is fast for small arrays (8 items)
  • formatTime() uses simple math operations (no Date object instantiation)

Type Safety

While this is JavaScript, the utils are designed to be defensive:
// esc() handles non-string inputs:
esc(null);        // Returns: ''
esc(undefined);   // Returns: ''
esc(42);          // Returns: '42'
esc('<b>Hi</b>'); // Returns: '&lt;b&gt;Hi&lt;/b&gt;'

// formatDate() returns empty string for invalid input:
formatDate(null);      // Returns: ''
formatDate(undefined); // Returns: ''

Build docs developers (and LLMs) love