Répond à deux besoins : permettre à chaque foyer de choisir quelles sources apparaissent dans ses onglets de recettes, et distinguer les sources à API officielle des sources scrapées. - RecipeSourceAdapter.official (booléen, sans défaut — chaque adaptateur doit le déclarer explicitement) synchronisé sur Source.official par syncRecipeSources. - HouseSource : table de jointure opt-in (House <-> Source) — aucune ligne = source masquée. Un foyer nouvellement créé ne voit aucune source tant qu'il ne les active pas explicitement. - GET /reference/sources (catalogue des sources implémentées, avec le flag officiel). - GET/PATCH /house/current/sources (lecture/remplacement complet des sources activées par le foyer courant). - recipe.service.ts : sourceVisibilityWhere() filtre désormais TOUS les onglets (perso/foyer/publique/favoris) — une recette sans source reste toujours visible ; une recette importée ne l'est que si sa source est activée pour le foyer du viewer. Un viewer sans foyer ne voit aucune recette sourcée. Côté web : - Nouvelle étape /onboarding/sources dans le wizard d'inscription, atteinte uniquement si un foyer vient d'être créé/rejoint (sinon on saute direct aux allergènes) ; s'auto-saute aussi si aucune source n'est encore implémentée (catalogue vide aujourd'hui). - Nouvelle section « Sources de recettes » dans /parametres/foyer (masquée dans les mêmes conditions), avec sauvegarde à la volée (même pattern que les autres préférences hot-saved). - SourceSelect (features/house/), grille de cases à cocher avec badge officiel/non-officielle, sur le même principe qu'AllergySelect. 172 tests backend passent (dont 25 nouveaux). Build et lint propres. Vérifié manuellement en navigateur : le parcours d'onboarding saute bien l'étape sources (catalogue vide) et affiche « 4 sur 4 » quand un foyer a été créé ; la section paramètres reste invisible tant qu'aucune source n'existe. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
43 lines
1.2 KiB
SCSS
43 lines
1.2 KiB
SCSS
// Same grid-of-checkbox-cards shape as `features/profile/profile-forms.scss`'s
|
|
// `.allergy-select` — kept as its own file/class rather than reused directly
|
|
// since this is household-scoped, not profile-scoped (see `SourceSelect.tsx`).
|
|
.source-select {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
|
|
gap: var(--space-xs) var(--space-md);
|
|
margin: var(--space-sm) 0 0;
|
|
padding: 0;
|
|
border: none;
|
|
|
|
legend {
|
|
grid-column: 1 / -1;
|
|
padding: 0;
|
|
font-size: var(--font-size-sm);
|
|
font-weight: 600;
|
|
}
|
|
|
|
&__option {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
margin-top: 0;
|
|
font-weight: 400;
|
|
font-size: var(--font-size-base);
|
|
}
|
|
|
|
// Official/unofficial marker — same "small pill" language as
|
|
// `settings-pages.scss`'s `.settings-page__member-badge`, neutral grey by
|
|
// default (unofficial/scraped) and tinted primary once official.
|
|
&__badge {
|
|
padding: 0.1rem 0.4rem;
|
|
font-size: var(--font-size-xs);
|
|
font-weight: 600;
|
|
color: var(--color-text-muted);
|
|
background: var(--color-surface-alt);
|
|
border-radius: var(--radius-base);
|
|
|
|
&.is-official {
|
|
color: var(--color-primary);
|
|
}
|
|
}
|
|
}
|