Retour aux projets

1Glink

LYA CV

Structurer des données de candidature complexes pour donner aux recruteurs une lecture claire et directement exploitable.

Produit
Analyse de candidatures
Rôle
Frontend Angular · UX/UI
Enjeu
Rendre la donnée actionnable
  • Angular
  • TypeScript
  • NGXS
  • RxJS
  • SCSS

01 · Le problème

Une quantité de données ne constitue pas encore une décision

Une candidature agrège un CV, une fiche de poste, des scores, des compétences, des expériences et des documents. Afficher toutes ces informations sans hiérarchie aurait seulement déplacé la complexité du backend vers le recruteur.

J’ai travaillé sur la structure des pages autant que sur leur intégration Angular : une vue d’ensemble pour comparer, puis une fiche détaillée qui explique les signaux et prépare la prochaine action.

Liste LYA CV organisée par poste avec indicateurs de suivi et candidatures.
Les KPI donnent le contexte global avant de parcourir les candidatures rattachées à chaque poste.

02 · Services et API

Protéger l’interface des variations du backend

Les formats exposés par une API répondent à une logique de transport. La vue a besoin d’un modèle plus stable, orienté vers la tâche du recruteur.

  1. 01 · Service

    Appeler l’API

    Le service regroupe les routes, paramètres et types de transport sans exposer HttpClient aux composants.

  2. 02 · État

    Orchestrer le chargement

    Les actions et sélecteurs distinguent chargement, absence, erreur et donnée disponible.

  3. 03 · Mapper

    Construire le ViewModel

    Les valeurs sont nettoyées, dédupliquées et regroupées dans des fonctions TypeScript testables.

  4. 04 · Composant

    Afficher un contrat stable

    Le template reçoit des libellés, statuts et collections déjà adaptés à son besoin de présentation.

Résultat Une valeur manquante ou un changement de contrat API ne force pas la duplication de conditions dans tous les templates.

03 · Fiche détaillée

Expliquer les résultats au lieu de les empiler

La fiche candidat doit permettre de comprendre pourquoi une compétence est validée, à vérifier ou absente.

  1. Relier attendu et observé

    Chaque compétence rapproche le besoin du poste et les preuves repérées dans le CV.

  2. Conserver le contexte

    Le parcours, les documents et les questions d’entretien restent accessibles dans la même page.

  3. Traiter les cas incomplets

    Une information absente reçoit un état explicite sans masquer le reste de la candidature.

Analyse détaillée d’un candidat avec compétences, documents et parcours.
La mise en page alterne synthèse, preuves et exploration détaillée sans enfermer chaque information dans une nouvelle carte.

04 · Exemple technique

Du contrat API au composant Angular

Les extraits suivants sont des exemples anonymisés et réécrits pour expliquer mon approche. Ils ne reproduisent ni le code ni les contrats internes de 1Glink.

Data access

Masquer le transport derrière une interface

Le composant dépend d’un contrat métier. L’implémentation HTTP peut ensuite évoluer ou être remplacée dans les tests.

export interface CandidateGateway {
  getCandidate(id: string): Observable<CandidateDto>;
}

@Injectable()
export class HttpCandidateGateway implements CandidateGateway {
  private readonly http = inject(HttpClient);

  getCandidate(id: string): Observable<CandidateDto> {
    return this.http.get<CandidateDto>(`/api/candidates/${id}`);
  }
}

ViewModel

Adapter les données une seule fois

La transformation centralise les valeurs absentes et les libellés afin d’alléger les composants.

export function toCandidateHeader(dto: CandidateDto): CandidateHeaderVm {
  const fullName = [dto.firstName, dto.lastName]
    .filter((value): value is string => Boolean(value?.trim()))
    .join(' ');

  return {
    id: dto.id,
    name: fullName || 'Profil à compléter',
    position: dto.position?.trim() || 'Poste non renseigné',
    score: dto.score ?? null,
  };
}

Test unitaire

Sécuriser les cas incomplets

Le test porte sur une règle observable qui doit rester stable même lorsque les données sont partielles.

it('creates a usable header from partial data', () => {
  const header = toCandidateHeader({
    id: 'candidate-1',
    firstName: 'Samira',
    lastName: null,
    position: null,
    score: null,
  });

  expect(header.name).toBe('Samira');
  expect(header.position).toBe('Poste non renseigné');
  expect(header.score).toBeNull();
});

05 · Cohérence UI

Des composants denses, mais un vocabulaire stable

Les KPI, statuts, actions et documents réutilisent les mêmes fondations afin que la densité d’information ne devienne pas une accumulation de styles locaux.

Couleurs

  • NuitTitres et données principales#171a33
  • IndigoActions et sélection#2457ff
  • BrumeStructure de page#f5f7fb
  • SuccèsCompétence validée#60c991
  • AttentionCompétence à vérifier#f5b85b

Typographie

Inter · Regular / Medium / Semibold

Comprendre une candidature en un regard.

Les libellés, preuves et statuts complètent les valeurs au lieu de laisser le score parler seul.