feat(groups): panneau groupe pro + 175 icones avec recherche
This commit is contained in:
@@ -422,10 +422,20 @@
|
|||||||
|
|
||||||
<!-- ==================== MODALE GROUPE ==================== -->
|
<!-- ==================== MODALE GROUPE ==================== -->
|
||||||
<div *ngIf="showGroupModal()" class="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4" (click)="closeGroupModal()">
|
<div *ngIf="showGroupModal()" class="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4" (click)="closeGroupModal()">
|
||||||
<div class="w-full max-w-md rounded-xl border border-slate-700 bg-slate-900 p-5 shadow-2xl" (click)="$event.stopPropagation()">
|
<div class="max-h-[90vh] w-full max-w-lg overflow-y-auto rounded-xl border border-slate-700 bg-slate-900 p-5 shadow-2xl" (click)="$event.stopPropagation()">
|
||||||
<h3 class="text-lg font-semibold text-slate-100">
|
<div class="flex items-center gap-3">
|
||||||
{{ editingGroup() ? 'Modifier le groupe' : 'Nouveau groupe' }}
|
<span
|
||||||
</h3>
|
class="flex h-11 w-11 shrink-0 items-center justify-center rounded-xl text-2xl transition-colors"
|
||||||
|
[style.background-color]="groupColor() + '26'"
|
||||||
|
[style.border]="'1px solid ' + groupColor() + '66'"
|
||||||
|
>{{ groupIcon() }}</span>
|
||||||
|
<div class="min-w-0">
|
||||||
|
<h3 class="truncate text-lg font-semibold text-slate-100">
|
||||||
|
{{ editingGroup() ? 'Modifier le groupe' : 'Nouveau groupe' }}
|
||||||
|
</h3>
|
||||||
|
<p class="truncate text-xs text-slate-400">{{ groupName() || 'Donnez un nom à votre groupe…' }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<label class="mt-4 block text-xs font-semibold uppercase tracking-wide text-slate-400">Nom</label>
|
<label class="mt-4 block text-xs font-semibold uppercase tracking-wide text-slate-400">Nom</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -435,41 +445,70 @@
|
|||||||
placeholder="Ex : Tech, Musique, Sport…"
|
placeholder="Ex : Tech, Musique, Sport…"
|
||||||
class="mt-1 w-full rounded-md border border-slate-700 bg-slate-800 px-3 py-2 text-sm text-slate-100 placeholder:text-slate-500 focus:border-red-500 focus:outline-none"
|
class="mt-1 w-full rounded-md border border-slate-700 bg-slate-800 px-3 py-2 text-sm text-slate-100 placeholder:text-slate-500 focus:border-red-500 focus:outline-none"
|
||||||
/>
|
/>
|
||||||
<label class="mt-4 block text-xs font-semibold uppercase tracking-wide text-slate-400">Icône</label>
|
<div class="mt-4 flex items-center justify-between gap-2">
|
||||||
<div class="mt-1 flex flex-wrap gap-1">
|
<label class="block text-xs font-semibold uppercase tracking-wide text-slate-400" for="group-icon-search">
|
||||||
|
Icône <span class="text-slate-500">({{ filteredIcons().length }}/{{ icons.length }})</span>
|
||||||
|
</label>
|
||||||
<button
|
<button
|
||||||
*ngFor="let icon of icons"
|
*ngIf="iconSearch()"
|
||||||
|
type="button"
|
||||||
|
(click)="iconSearch.set('')"
|
||||||
|
class="text-xs text-slate-400 underline hover:text-slate-200"
|
||||||
|
>
|
||||||
|
Effacer
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="relative mt-1">
|
||||||
|
<svg class="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||||
|
</svg>
|
||||||
|
<input
|
||||||
|
id="group-icon-search"
|
||||||
|
type="text"
|
||||||
|
[ngModel]="iconSearch()"
|
||||||
|
(ngModelChange)="iconSearch.set($event)"
|
||||||
|
placeholder="Rechercher : musique, sport, cuisine…"
|
||||||
|
class="w-full rounded-md border border-slate-700 bg-slate-800 py-2 pl-9 pr-3 text-sm text-slate-100 placeholder:text-slate-500 focus:border-red-500 focus:outline-none"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="filteredIcons().length > 0; else noGroupIcon" class="mt-2 grid max-h-48 grid-cols-8 gap-1 overflow-y-auto rounded-lg border border-slate-800 bg-slate-900/60 p-2 sm:grid-cols-10">
|
||||||
|
<button
|
||||||
|
*ngFor="let icon of filteredIcons()"
|
||||||
type="button"
|
type="button"
|
||||||
(click)="groupIcon.set(icon)"
|
(click)="groupIcon.set(icon)"
|
||||||
class="rounded-md px-2 py-1 text-lg"
|
[title]="icon"
|
||||||
|
[attr.aria-label]="'Icône ' + icon"
|
||||||
|
[attr.aria-pressed]="groupIcon() === icon"
|
||||||
|
class="rounded-md px-1 py-1.5 text-xl transition"
|
||||||
[class.bg-red-500/20]="groupIcon() === icon"
|
[class.bg-red-500/20]="groupIcon() === icon"
|
||||||
[class.ring-1]="groupIcon() === icon"
|
[class.ring-1]="groupIcon() === icon"
|
||||||
[class.ring-red-500]="groupIcon() === icon"
|
[class.ring-red-500]="groupIcon() === icon"
|
||||||
[class.hover:bg-slate-800]="groupIcon() !== icon"
|
[class.hover:bg-slate-800]="groupIcon() !== icon"
|
||||||
>{{ icon }}</button>
|
>{{ icon }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
<ng-template #noGroupIcon>
|
||||||
|
<p class="mt-2 rounded-lg border border-dashed border-slate-700 p-4 text-center text-sm text-slate-400">
|
||||||
|
Aucune icône pour « {{ iconSearch() }} ».
|
||||||
|
</p>
|
||||||
|
</ng-template>
|
||||||
<label class="mt-4 block text-xs font-semibold uppercase tracking-wide text-slate-400">Couleur</label>
|
<label class="mt-4 block text-xs font-semibold uppercase tracking-wide text-slate-400">Couleur</label>
|
||||||
<div class="mt-1 flex flex-wrap gap-1">
|
<div class="mt-1 flex flex-wrap gap-1.5">
|
||||||
<button
|
<button
|
||||||
*ngFor="let color of colors"
|
*ngFor="let color of colors"
|
||||||
type="button"
|
type="button"
|
||||||
(click)="groupColor.set(color)"
|
(click)="groupColor.set(color)"
|
||||||
class="h-7 w-7 rounded-full"
|
class="h-7 w-7 rounded-full transition"
|
||||||
[style.background-color]="color"
|
[style.background-color]="color"
|
||||||
[class.ring-2]="groupColor() === color"
|
[class.ring-2]="groupColor() === color"
|
||||||
[class.ring-white]="groupColor() === color"
|
[class.ring-white]="groupColor() === color"
|
||||||
|
[class.ring-offset-2]="groupColor() === color"
|
||||||
|
[class.ring-offset-slate-900]="groupColor() === color"
|
||||||
[title]="color"
|
[title]="color"
|
||||||
|
[attr.aria-label]="'Couleur ' + color"
|
||||||
|
[attr.aria-pressed]="groupColor() === color"
|
||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4 flex items-center gap-2 rounded-lg border border-slate-700 bg-slate-800/60 p-3">
|
<div class="mt-5 flex justify-end gap-2 border-t border-slate-800 pt-4">
|
||||||
<span
|
|
||||||
class="flex h-10 w-10 items-center justify-center rounded-lg text-xl"
|
|
||||||
[style.background-color]="groupColor() + '26'"
|
|
||||||
[style.border]="'1px solid ' + groupColor() + '66'"
|
|
||||||
>{{ groupIcon() }}</span>
|
|
||||||
<span class="font-semibold text-slate-100">{{ groupName() || 'Aperçu du groupe' }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="mt-5 flex justify-end gap-2">
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
(click)="closeGroupModal()"
|
(click)="closeGroupModal()"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
|||||||
import {
|
import {
|
||||||
GROUP_COLORS,
|
GROUP_COLORS,
|
||||||
GROUP_ICONS,
|
GROUP_ICONS,
|
||||||
|
GROUP_ICON_KEYWORDS,
|
||||||
SubscriptionsService,
|
SubscriptionsService,
|
||||||
type SubscriptionGroup,
|
type SubscriptionGroup,
|
||||||
type SubscriptionItem,
|
type SubscriptionItem,
|
||||||
@@ -67,6 +68,18 @@ export class SubscriptionsComponent {
|
|||||||
groupColor = signal<string>(GROUP_COLORS[0]);
|
groupColor = signal<string>(GROUP_COLORS[0]);
|
||||||
groupIcon = signal<string>(GROUP_ICONS[0]);
|
groupIcon = signal<string>(GROUP_ICONS[0]);
|
||||||
groupSaving = signal<boolean>(false);
|
groupSaving = signal<boolean>(false);
|
||||||
|
iconSearch = signal<string>('');
|
||||||
|
|
||||||
|
/** Icônes filtrées par la recherche (emoji ou mot-clé FR/EN). */
|
||||||
|
readonly filteredIcons = computed(() => {
|
||||||
|
const q = this.iconSearch().trim().toLowerCase();
|
||||||
|
if (!q) return this.icons;
|
||||||
|
return this.icons.filter((emoji) => {
|
||||||
|
if (emoji.includes(q)) return true;
|
||||||
|
const kw = (GROUP_ICON_KEYWORDS[emoji] || '').toLowerCase();
|
||||||
|
return kw.split(/\s+/).some((w) => w.startsWith(q)) || kw.includes(q);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// --- Assigneur de groupes (par ligne) ---
|
// --- Assigneur de groupes (par ligne) ---
|
||||||
pickerFor = signal<number | null>(null);
|
pickerFor = signal<number | null>(null);
|
||||||
@@ -142,6 +155,7 @@ export class SubscriptionsComponent {
|
|||||||
this.groupName.set('');
|
this.groupName.set('');
|
||||||
this.groupColor.set(GROUP_COLORS[this.groups().length % GROUP_COLORS.length]);
|
this.groupColor.set(GROUP_COLORS[this.groups().length % GROUP_COLORS.length]);
|
||||||
this.groupIcon.set(GROUP_ICONS[this.groups().length % GROUP_ICONS.length]);
|
this.groupIcon.set(GROUP_ICONS[this.groups().length % GROUP_ICONS.length]);
|
||||||
|
this.iconSearch.set('');
|
||||||
this.showGroupModal.set(true);
|
this.showGroupModal.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +165,7 @@ export class SubscriptionsComponent {
|
|||||||
this.groupName.set(group.name);
|
this.groupName.set(group.name);
|
||||||
this.groupColor.set(group.color);
|
this.groupColor.set(group.color);
|
||||||
this.groupIcon.set(group.icon);
|
this.groupIcon.set(group.icon);
|
||||||
|
this.iconSearch.set('');
|
||||||
this.showGroupModal.set(true);
|
this.showGroupModal.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,16 +31,121 @@ interface GroupsResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const GROUP_COLORS = [
|
export const GROUP_COLORS = [
|
||||||
'#ef4444', '#f97316', '#f59e0b', '#84cc16', '#22c55e',
|
'#ef4444', '#f43f5e', '#f97316', '#f59e0b', '#eab308', '#84cc16',
|
||||||
'#14b8a6', '#06b6d4', '#3b82f6', '#8b5cf6', '#d946ef',
|
'#22c55e', '#10b981', '#14b8a6', '#06b6d4', '#0ea5e9', '#3b82f6',
|
||||||
'#ec4899', '#64748b',
|
'#8b5cf6', '#a855f6', '#d946ef', '#ec4899', '#fb7185', '#64748b',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** ~130 icônes classées (général, musique, gaming, sport, tech, cuisine, voyage, ciné, éducation, news, santé, nature, humour, art, lifestyle, auto, business). */
|
||||||
export const GROUP_ICONS = [
|
export const GROUP_ICONS = [
|
||||||
'📁', '🎵', '🎮', '📰', '⚽', '🎓', '💻', '🤖',
|
// Général
|
||||||
'🏥', '🍳', '✈️', '🎬', '📚', '💡', '🔬', '⭐',
|
'📁', '⭐', '❤️', '🔥', '💡', '📌', '🎯', '🏆', '💎', '🎁', '⚡', '🌟', '💯', '✅', '🆕',
|
||||||
|
// Musique
|
||||||
|
'🎵', '🎶', '🎸', '🎹', '🎧', '🎤', '🥁', '🎺', '🎻', '📻',
|
||||||
|
// Gaming
|
||||||
|
'🎮', '🕹️', '🎲', '🃏', '♟️', '👾', '🤖',
|
||||||
|
// Sport
|
||||||
|
'⚽', '🏀', '🏈', '⚾', '🎾', '🏐', '🏓', '🏸', '🥊', '🏊', '🚴', '🏃', '⛷️', '🏂', '🛹', '🏄', '🥋', '🏎️', '🏁', '🏅',
|
||||||
|
// Tech & science
|
||||||
|
'💻', '🖥️', '⌨️', '🖱️', '💾', '💿', '📱', '🛰️', '🔬', '🧬', '🧪', '🔭', '🪐', '🌌', '🧠', '⚙️', '🔧', '🛠️', '📊',
|
||||||
|
// Cuisine
|
||||||
|
'🍳', '🍕', '🍔', '🍰', '🍩', '🍺', '☕', '🍷', '🧁', '🥗', '🍎', '🌶️',
|
||||||
|
// Voyage
|
||||||
|
'✈️', '🧳', '🗺️', '🏖️', '🏕️', '🗽', '🗼', '🏰', '⛰️', '🎒',
|
||||||
|
// Cinéma & TV
|
||||||
|
'🎬', '📺', '🍿', '🎞️', '📽️',
|
||||||
|
// Éducation
|
||||||
|
'🎓', '📚', '📖', '✏️', '📝', '🧮', '🌍', '🗣️',
|
||||||
|
// News, finance & politique
|
||||||
|
'🗞️', '📢', '🏛️', '💹', '💰', '🪙', '🏦', '📈',
|
||||||
|
// Santé & bien-être
|
||||||
|
'🏥', '🩺', '💊', '🧘', '🏋️', '😴',
|
||||||
|
// Nature & animaux
|
||||||
|
'🌿', '🌳', '🌸', '🐶', '🐱', '🐦', '🐟', '🌊', '🦁', '🐝',
|
||||||
|
// Humour
|
||||||
|
'😂', '🤣', '😜', '🎭', '🤡', '🎪',
|
||||||
|
// Art, design & photo
|
||||||
|
'🖌️', '🎨', '📷', '📸', '🖼️', '✒️', '🎼',
|
||||||
|
// Lifestyle & famille
|
||||||
|
'📹', '🤳', '💄', '👗', '👟', '🏠', '🐾', '👶', '🧸',
|
||||||
|
// Auto & moto
|
||||||
|
'🚗', '🏍️', '🚚', '🚲', '⛽',
|
||||||
|
// Business & bureau
|
||||||
|
'💼', '📅', '⏰', '📞', '📧', '🏢',
|
||||||
|
// Météo & fêtes
|
||||||
|
'🌙', '☀️', '🌧️', '❄️', '🎄', '🎃', '🎉', '🎈',
|
||||||
|
// Avis & shopping
|
||||||
|
'📦', '🛒', '💳', '🔑',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** Mots-clés de recherche par icône (FR + EN). Défaut : nom générique. */
|
||||||
|
export const GROUP_ICON_KEYWORDS: Record<string, string> = {
|
||||||
|
'📁': 'dossier folder fichier file', '⭐': 'favori star etoile favorite', '❤️': 'coeur love coeur favori heart',
|
||||||
|
'🔥': 'feu fire tendance hot trending viral', '💡': 'idee idea astuce tips', '📌': 'punaise pin epingle important',
|
||||||
|
'🎯': 'cible target objectif', '🏆': 'trophee trophy victoire win sport', '💎': 'diamant diamond premium',
|
||||||
|
'🎁': 'cadeau gift', '⚡': 'eclair lightning energie actu rapide', '🌟': 'etoile star brillant', '💯': 'cent parfait perfect',
|
||||||
|
'✅': 'valide check ok', '🆕': 'nouveau new',
|
||||||
|
'🎵': 'musique music note chanson song', '🎶': 'musique music notes concert', '🎸': 'guitare guitar rock metal',
|
||||||
|
'🎹': 'piano clavier keyboard', '🎧': 'casque headphone audio ecoute', '🎤': 'micro microphone chant sing karaoke vocal',
|
||||||
|
'🥁': 'batterie drum', '🎺': 'trompette trumpet', '🎻': 'violon violin classique', '📻': 'radio',
|
||||||
|
'🎮': 'jeu video game gaming manette controller esport', '🕹️': 'arcade retro joystick', '🎲': 'de dice jeu board',
|
||||||
|
'🃏': 'carte card poker', '♟️': 'echec chess strategie', '👾': 'alien pixel retrogaming invader',
|
||||||
|
'🤖': 'robot robot ia ai tech', '⚽': 'foot football soccer sport', '🏀': 'basket basketball sport',
|
||||||
|
'🏈': 'football americain us sport', '⚾': 'baseball sport', '🎾': 'tennis sport', '🏐': 'volley volleyball sport',
|
||||||
|
'🏓': 'pingpong tennis table sport', '🏸': 'badminton sport', '🥊': 'boxe boxing combat sport',
|
||||||
|
'🏊': 'natation swim piscine sport', '🚴': 'velo cycling cyclisme sport', '🏃': 'course run running jogging sport',
|
||||||
|
'⛷️': 'ski hiver sport', '🏂': 'snowboard hiver sport', '🛹': 'skate skateboard', '🏄': 'surf vague sport',
|
||||||
|
'🥋': 'judo karate arts martiaux combat', '🏎️': 'course auto racing f1 formule', '🏁': 'drapeau finish arrivee course',
|
||||||
|
'🏅': 'medaille medal sport victoire', '💻': 'ordi ordinateur computer portable laptop dev code',
|
||||||
|
'🖥️': 'ecran monitor bureau setup desktop', '⌨️': 'clavier keyboard', '🖱️': 'souris mouse',
|
||||||
|
'💾': 'disquette save sauvegarde disque', '💿': 'cd dvd disque', '📱': 'telephone phone mobile smartphone app',
|
||||||
|
'🛰️': 'satellite espace space', '🔬': 'microscope science labo recherche', '🧬': 'adn dna genetique science',
|
||||||
|
'🧪': 'eprouvette test chimie chemistry experience', '🔭': 'telescope espace astronomie space',
|
||||||
|
'🪐': 'planete planet saturne espace', '🌌': 'galaxie galaxy espace univers', '🧠': 'cerveau brain neuro',
|
||||||
|
'⚙️': 'engrenage reglage settings parametre', '🔧': 'cle outil bricolage tool mecanique',
|
||||||
|
'🛠️': 'outils bricolage tools diy makers', '📊': 'graphique stats chart data analyse',
|
||||||
|
'🍳': 'cuisine cooking oeuf recette food', '🍕': 'pizza food', '🍔': 'burger food',
|
||||||
|
'🍰': 'gateau cake dessert patisserie', '🍩': 'donut food', '🍺': 'biere beer', '☕': 'cafe coffee',
|
||||||
|
'🍷': 'vin wine', '🧁': 'cupcake dessert', '🥗': 'salade salad healthy sante', '🍎': 'pomme apple fruit',
|
||||||
|
'🌶️': 'piment spicy piquant', '✈️': 'avion travel voyage plane vacances', '🧳': 'valise bagage luggage voyage',
|
||||||
|
'🗺️': 'carte map monde world voyage', '🏖️': 'plage beach vacances holiday ete', '🏕️': 'camping nature',
|
||||||
|
'🗽': 'statue liberte new york usa voyage', '🗼': 'tour eiffel paris tokyo voyage', '🏰': 'chateau castle histoire',
|
||||||
|
'⛰️': 'montagne mountain rando nature', '🎒': 'sac dos backpack voyage ecole',
|
||||||
|
'🎬': 'cinema film movie serie tournage clap', '📺': 'tele tv television serie', '🍿': 'popcorn cinema film',
|
||||||
|
'🎞️': 'pellicule film cinema', '📽️': 'projecteur projector cinema',
|
||||||
|
'🎓': 'diplome education ecole school universite cours', '📚': 'livres books lecture read',
|
||||||
|
'📖': 'livre ouvert book lecture', '✏️': 'crayon pencil ecole', '📝': 'note memo ecrire write',
|
||||||
|
'🧮': 'calculatrice boulier math maths', '🌍': 'terre monde earth geographie', '🗣️': 'parole langue language podcast discussion',
|
||||||
|
'🗞️': 'journal news actu newspaper presse', '📢': 'megaphone annonce announce actu',
|
||||||
|
'🏛️': 'politique parliament mairie politics debat', '💹': 'bourse finance chart money',
|
||||||
|
'💰': 'argent money finance crypto richesse', '🪙': 'piece coin crypto monnaie',
|
||||||
|
'🏦': 'banque bank economie', '📈': 'graphique hausse growth bourse',
|
||||||
|
'🏥': 'hopital hospital sante health', '🩺': 'stethoscope docteur doctor medecin sante',
|
||||||
|
'💊': 'medicament pill sante', '🧘': 'yoga meditation bienetre', '🏋️': 'musculation sport gym fitness',
|
||||||
|
'😴': 'dodo sleep nuit', '🌿': 'nature plante plant jardin', '🌳': 'arbre tree foret',
|
||||||
|
'🌸': 'fleur flower printemps', '🐶': 'chien dog animaux', '🐱': 'chat cat animaux',
|
||||||
|
'🐦': 'oiseau bird animaux', '🐟': 'poisson fish peche animaux', '🌊': 'vague wave mer sea ocean surf',
|
||||||
|
'🦁': 'lion animaux', '🐝': 'abeille bee nature',
|
||||||
|
'😂': 'rire lol humour funny laugh', '🤣': 'mort rire lol humour', '😜': 'clin oeil blague joke humour',
|
||||||
|
'🎭': 'theatre masque theatre spectacle', '🤡': 'clown humour', '🎪': 'cirque circus spectacle',
|
||||||
|
'🖌️': 'pinceau art paint dessin draw', '🎨': 'palette artiste artist peinture',
|
||||||
|
'📷': 'photo appareil camera photography', '📸': 'flash photo', '🖼️': 'tableau cadre frame expo',
|
||||||
|
'✒️': 'plume stylo pen ecriture write', '🎼': 'partition musique music sheet classique',
|
||||||
|
'📹': 'camera video vlog youtube', '🤳': 'selfie photo', '💄': 'maquillage makeup beaute beauty',
|
||||||
|
'👗': 'robe mode fashion vetement', '👟': 'chaussure basket sneaker sport mode',
|
||||||
|
'🏠': 'maison home immo jardinage', '🐾': 'patte animaux pet', '👶': 'bebe baby enfant kid famille',
|
||||||
|
'🧸': 'nounours enfant jouet', '🚗': 'voiture car auto automobile',
|
||||||
|
'🏍️': 'moto motorbike', '🚚': 'camion truck', '🚲': 'velo bike cyclisme',
|
||||||
|
'⛽': 'essence fuel station', '💼': 'mallette travail work business bureau office',
|
||||||
|
'📅': 'calendrier agenda calendar date', '⏰': 'reveil alarme morning matin',
|
||||||
|
'📞': 'telephone call appel', '📧': 'email mail courrier', '🏢': 'immeuble entreprise building company startup',
|
||||||
|
'🌙': 'nuit night lune moon', '☀️': 'soleil sun meteo weather ete', '🌧️': 'pluie rain meteo',
|
||||||
|
'❄️': 'neige snow hiver winter', '🎄': 'noel christmas sapin fete', '🎃': 'halloween citrouille',
|
||||||
|
'🎉': 'fete party anniversaire birthday', '🎈': 'ballon balloon fete',
|
||||||
|
'📦': 'colis paquet unboxing avis review test', '🛒': 'courses shopping panier cart',
|
||||||
|
'💳': 'carte bancaire paiement pay', '🔑': 'cle key',
|
||||||
|
};
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class SubscriptionsService {
|
export class SubscriptionsService {
|
||||||
private http = inject(HttpClient);
|
private http = inject(HttpClient);
|
||||||
|
|||||||
Reference in New Issue
Block a user