import {apiFetch} from './api.js'; // The groups a user can show on the public profile; the overview numbers are always there. export const PROFILE_STAT_GROUPS = ['PILE', 'TREND', 'TOP_GAMES', 'TASTE', 'HABITS', 'FINISHED']; /** * PUT /api/users/settings/profile-stats on Auth. The caller handles the response status. */ export const saveProfileStats = (groups) => apiFetch(`${import.meta.env.VITE_API_URL}/api/users/settings/profile-stats`, { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({groups}), }); /** * @param groups comma separated stat groups of Core (StatGroup); empty for all */ export const statsUrl = (groups) => { const query = groups ? `?groups=${groups}` : ''; return `${import.meta.env.VITE_CORE_API_URL}/api/library/stats${query}`; }; /** * The i18n key of an IGDB genre name, e.g. "Role-playing (RPG)" -> "ROLE_PLAYING_RPG". Callers fall back to the * name, so a genre IGDB adds later still shows. */ export const genreKey = (name) => name.toUpperCase().replace(/[^A-Z0-9]+/g, '_').replace(/^_|_$/g, ''); export const formatDecimal = (value, locale, digits = 1) => value.toLocaleString(locale, {minimumFractionDigits: 0, maximumFractionDigits: digits}); export const formatPercent = (share, locale) => share.toLocaleString(locale, {style: 'percent', maximumFractionDigits: 0}); const DAY_MS = 24 * 60 * 60 * 1000; const dayNumber = (day) => Math.round(Date.parse(`${day}T00:00:00Z`) / DAY_MS); /** * Points of an SVG polyline for the pile per day, oldest left. x follows the date, so days without a snapshot * keep their width. The y axis starts at 0, so a small change looks small. One day gives a flat line over the * whole width. */ export const trendPoints = (days, width, height) => { if (days.length === 0) return ''; const max = Math.max(1, ...days.map((d) => d.backlogGames)); const y = (d) => height - (d.backlogGames / max) * height; if (days.length === 1) return `0,${y(days[0])} ${width},${y(days[0])}`; const first = dayNumber(days[0].day); const span = dayNumber(days[days.length - 1].day) - first; return days.map((d) => `${((dayNumber(d.day) - first) / span) * width},${y(d)}`).join(' '); };