{# # ============================================================================ # MOLECULE: TOOL CARD # ============================================================================ # # Carte d'outil pour le dashboard. # Affiche les statistiques, sparkline 30 jours, et gradient décoratif. # Chaque outil a sa propre couleur d'accent dérivée du code. # # ============================================================================ # COMPOSITION (Atomes utilisés) # ============================================================================ # # - _atoms/icon/icon.html.twig # - _atoms/badge/badge.html.twig # # ============================================================================ # PARAMETRES # ============================================================================ # # | Paramètre | Type | Défaut | Description | # |---------------|---------|------------|---------------------------------------| # | name | string | (requis) | Nom de l'outil (Moodia, Serenia...) | # | code | string | (requis) | Code de l'outil (moodia, serenia...) | # | tagline | string | null | Sous-titre (ex: "PDF → Cours Moodle") | # | description | string | null | Description de l'outil | # | href | string | null | Lien vers l'outil | # | isNew | bool | false | Afficher badge nouveauté | # | newLabel | string | 'NEW' | Libellé du badge isNew (ex: BETA) | # | proBadge | bool | false | Affiche un badge « PRO » (prioritaire sur isNew) | # | stats | object | {} | Statistiques de l'outil | # | - generated | int | 0 | Nombre de contenus générés | # | - items | string | 'contenus' | Label des contenus | # | - tokens | int | 0 | Tokens consommés | # | - wh | float | 0 | Énergie en Wh | # | - lastUsed | string | null | Dernière utilisation | # | percentage | int | 0 | Pourcentage tokens vs total | # | weekUsage | array | [] | Usage par jour (30 valeurs) | # | locked | bool | false | Outil verrouillé | # | class | string | '' | Classes additionnelles | # # ============================================================================ # COULEURS PAR OUTIL # ============================================================================ # # | Code | Couleur | Token CSS | # |------------|-----------|--------------------------| # | moodia | Bleu | primary (#0C81E4) | # | serenia | Violet | cohorts (#8b5cf6) | # | slidia | Orange | warning (#F59E0B) | # | monalisia | Rose | pink (#EC4899) | # | castia | Vert | success (#309344) | # | sam | Cyan | info (#0EA5E9) | # # ============================================================================ #} {# @tailwind-safelist (Tailwind JIT scans raw source, so these literals ensure dynamic bg-{{ tc }} classes are generated) bg-primary bg-cohorts bg-warning bg-error bg-success bg-info bg-pink bg-primary/5 bg-cohorts/5 bg-warning/5 bg-error/5 bg-success/5 bg-info/5 bg-pink/5 bg-primary/6 bg-cohorts/6 bg-warning/6 bg-error/6 bg-success/6 bg-info/6 bg-pink/6 bg-primary/8 bg-cohorts/8 bg-warning/8 bg-error/8 bg-success/8 bg-info/8 bg-pink/8 bg-primary/10 bg-cohorts/10 bg-warning/10 bg-error/10 bg-success/10 bg-info/10 bg-pink/10 text-primary text-cohorts text-warning text-error text-success text-info text-pink text-primary/50 text-cohorts/50 text-warning/50 text-error/50 text-success/50 text-info/50 text-pink/50 text-primary/70 text-cohorts/70 text-warning/70 text-error/70 text-success/70 text-info/70 text-pink/70 border-primary/12 border-cohorts/12 border-warning/12 border-error/12 border-success/12 border-info/12 border-pink/12 #} {# ============================================================================ CONFIGURATION DES VALEURS PAR DÉFAUT ============================================================================ #} {% set name = name ?? 'Outil' %} {% set code = code ?? 'moodia' %} {% set tagline = tagline ?? null %} {% set description = description ?? null %} {% set href = href ?? null %} {% set isNew = isNew ?? false %} {% set newLabel = newLabel ?? 'NEW' %} {% set proBadge = proBadge ?? false %} {% set stats = stats ?? {} %} {% set percentage = percentage ?? 0 %} {% set weekUsage = weekUsage ?? [] %} {% set locked = locked ?? false %} {% set statColumns = statColumns ?? null %} {% set class = class ?? '' %} {% set generated = stats.generated ?? 0 %} {% set items = stats.items ?? 'contenus' %} {% set tokens = stats.tokens ?? 0 %} {% set wh = stats.wh ?? 0 %} {% set lastUsed = stats.lastUsed ?? null %} {% set medianCost = stats.medianCost ?? 0 %} {# ============================================================================ COULEUR PAR OUTIL — hex DB via tool_color_details (fallback: token Tailwind) ============================================================================ #} {% set tc = color ?? (tool_colors[code] ?? 'primary') %} {% set td = tool_color_details[code] ?? {} %} {% set hex = td.primary ?? null %} {# Sparkline : vraies données, simulation, ou ligne plate si jamais utilisé #} {% set hasRealData = weekUsage|length > 0 and weekUsage|filter(v => v > 0)|length > 0 %} {% if hasRealData %} {% set sparkData = weekUsage %} {% elseif lastUsed %} {% set sparkData = [1, 0, 2, 1, 3, 2, 1, 4, 2, 3, 1, 0, 2, 5, 3, 2, 1, 3, 4, 2, 1, 0, 3, 2, 4, 3, 1, 2, 3, 2] %} {% else %} {% set sparkData = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] %} {% endif %} {% set maxWeekVal = 1 %} {% for val in sparkData %} {% if val > maxWeekVal %}{% set maxWeekVal = val %}{% endif %} {% endfor %} {# ============================================================================ RENDU HTML ============================================================================ #} {% set isClickable = href and not locked %} {% if isClickable %} {% else %}
{% endif %} {# ===== OVERLAY VERROUILLÉ — incite à l'upgrade ===== #} {% if locked %}
{% include '_atoms/icon/icon.html.twig' with { name: 'lock', size: 'lg', color: 'primary' } only %}
Disponible avec Pro
Débloquez {{ name }} dès maintenant
{% include '_atoms/icon/icon.html.twig' with { name: 'arrow-up', size: 'xs', color: 'white' } only %} Passer en pro
{% endif %} {# ===== GRADIENT DÉCORATIF (radial, coin haut-droit) ===== #} {% if hex %}
{% else %}
{% endif %} {# ===== HEADER ZONE ===== #}
{# Icône outil #} {% if code == 'sam' %}
{% include '_atoms/logo/logo.html.twig' with { variant: 'simple', size: 'xs', tint: 'cohorts' } only %}
{% elseif hex %}
{% include '_atoms/icon/icon.html.twig' with { name: 'bubul-' ~ code, size: 'lg', color: tc, colorPrimary: hex, colorSecondary: td.secondary ?? null } only %}
{% else %}
{% include '_atoms/icon/icon.html.twig' with { name: 'bubul-' ~ code, size: 'lg', color: tc } only %}
{% endif %} {# Contenu #}
{{ name }} {% if proBadge %} {% include '_atoms/badge/pro-badge.html.twig' only %} {% elseif isNew %} {% include '_atoms/badge/badge.html.twig' with { label: newLabel, variant: hex ? null : 'success', customColor: hex ?? null, size: 'xs' } only %} {% endif %}
{% if tagline %}
{{ tagline }}
{% endif %} {% if description %}

{{ description }}

{% endif %}
{% if not locked %} {# Flèche décorative (visible au hover) — À LA COULEUR DE L'OUTIL. L'atom icon N'ACCEPTE PAS de param « style » : la teinte hex (DB) doit passer par colorPrimary/colorSecondary, comme l'icône principale ci-dessus. Sans hex, on retombe sur le token « color: tc ». #}
{% include '_atoms/icon/icon.html.twig' with { name: 'chevron-right', size: 'xs', color: tc, colorPrimary: hex ?? null, colorSecondary: hex ?? null } only %}
{% endif %}
{# ===== STATS ROW ===== #} {% set defaultColumns = [ { value: generated|format_number(locale='fr'), label: items }, { value: tokens|format_number(locale='fr'), label: 'tokens' }, { value: wh|number_format(1, ',', ' '), label: 'Wh' } ] %} {% set columns = statColumns ?? defaultColumns %}
{% for col in columns %}
{{ col.value }}
{{ col.label }}
{% endfor %}
{# ===== FOOTER BAR ===== #} {% if isClickable %}{% else %}
{% endif %}