Compare commits
26 Commits
447f3d4137
...
e8b6d906e6
| Author | SHA1 | Date | |
|---|---|---|---|
| e8b6d906e6 | |||
| ae0be04964 | |||
| ca98821b3e | |||
| b1a80f85c9 | |||
| e713c05da1 | |||
| 51d279e341 | |||
| fffe8cd202 | |||
| 619e39219f | |||
| 6749f2025a | |||
| 119edbcfb4 | |||
| 33cc7a9191 | |||
| 10ebc77ba1 | |||
| f9477d3fbe | |||
| 4d37131301 | |||
| 04b910295c | |||
| c136f28f12 | |||
| 4b176b7083 | |||
| 00c42c7bee | |||
| 42c569e491 | |||
| d32d956b0e | |||
| 1fca0cf132 | |||
| b16dd4b55c | |||
| 8682421453 | |||
| dfe7daed14 | |||
| 11aa66feff | |||
| d23f3c9f4f |
18
.gitattributes
vendored
Normal file
18
.gitattributes
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Fins de ligne : toujours LF dans le dépôt (évite les conflits Linux/Windows)
|
||||||
|
* text=auto eol=lf
|
||||||
|
|
||||||
|
# Fichiers binaires : pas de conversion
|
||||||
|
*.png binary
|
||||||
|
*.jpg binary
|
||||||
|
*.jpeg binary
|
||||||
|
*.gif binary
|
||||||
|
*.ico binary
|
||||||
|
*.webp binary
|
||||||
|
*.pdf binary
|
||||||
|
*.woff binary
|
||||||
|
*.woff2 binary
|
||||||
|
*.ttf binary
|
||||||
|
*.eot binary
|
||||||
|
|
||||||
|
# Scripts shell : toujours LF
|
||||||
|
*.sh text eol=lf
|
||||||
7
check_hash.js
Normal file
7
check_hash.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
|
||||||
|
const pass = '!Bezons2014';
|
||||||
|
|
||||||
|
bcrypt.hash(pass, 10).then(hash => {
|
||||||
|
console.log('New Hash:', hash);
|
||||||
|
}).catch(err => console.error(err));
|
||||||
@ -840,7 +840,7 @@ Créer l'écran de création de mot de passe (lien reçu par email).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Ticket #44 : [Frontend] Dashboard Gestionnaire - Structure
|
### Ticket #44 : [Frontend] Dashboard Gestionnaire - Structure ✅
|
||||||
**Estimation** : 2h
|
**Estimation** : 2h
|
||||||
**Labels** : `frontend`, `p3`, `gestionnaire`
|
**Labels** : `frontend`, `p3`, `gestionnaire`
|
||||||
|
|
||||||
@ -848,9 +848,10 @@ Créer l'écran de création de mot de passe (lien reçu par email).
|
|||||||
Créer la structure du dashboard gestionnaire avec 2 onglets.
|
Créer la structure du dashboard gestionnaire avec 2 onglets.
|
||||||
|
|
||||||
**Tâches** :
|
**Tâches** :
|
||||||
- [ ] Layout avec 2 onglets (Parents / AM)
|
- [x] Dashboard gestionnaire = même shell que admin (sans onglet Paramètres), libellé « Gestionnaire »
|
||||||
- [ ] Navigation entre onglets
|
- [x] Réutilisation du widget UserManagementPanel (ex-AdminUserManagementPanel) avec 3 onglets (Gestionnaires, Parents, Assistantes maternelles) ; onglet Administrateurs masqué
|
||||||
- [ ] État vide ("Aucune demande")
|
- [x] Redirection login rôle `gestionnaire` vers `/gestionnaire-dashboard`
|
||||||
|
- [ ] État vide dédié ("Aucune demande") — optionnel, contenu actuel = listes existantes
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ Num | Etat | Titre
|
|||||||
41 | closed | [Frontend] Inscription AM - Panneau 2 (Infos pro)
|
41 | closed | [Frontend] Inscription AM - Panneau 2 (Infos pro)
|
||||||
42 | closed | [Frontend] Inscription AM - Finalisation
|
42 | closed | [Frontend] Inscription AM - Finalisation
|
||||||
43 | open | [Frontend] Écran Création Mot de Passe
|
43 | open | [Frontend] Écran Création Mot de Passe
|
||||||
44 | open | [Frontend] Dashboard Gestionnaire - Structure
|
44 | closed | [Frontend] Dashboard Gestionnaire - Structure
|
||||||
45 | open | [Frontend] Dashboard Gestionnaire - Liste Parents
|
45 | open | [Frontend] Dashboard Gestionnaire - Liste Parents
|
||||||
46 | open | [Frontend] Dashboard Gestionnaire - Liste AM
|
46 | open | [Frontend] Dashboard Gestionnaire - Liste AM
|
||||||
47 | open | [Frontend] Écran Changement MDP Obligatoire
|
47 | open | [Frontend] Écran Changement MDP Obligatoire
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
import '../../models/am_registration_data.dart';
|
import '../../models/am_registration_data.dart';
|
||||||
import '../../utils/data_generator.dart';
|
|
||||||
import '../../widgets/personal_info_form_screen.dart';
|
import '../../widgets/personal_info_form_screen.dart';
|
||||||
import '../../models/card_assets.dart';
|
import '../../models/card_assets.dart';
|
||||||
|
|
||||||
@ -14,19 +13,17 @@ class AmRegisterStep1Screen extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final registrationData = Provider.of<AmRegistrationData>(context, listen: false);
|
final registrationData = Provider.of<AmRegistrationData>(context, listen: false);
|
||||||
|
|
||||||
// Générer des données de test si vide
|
// Données de test : Marie DUBOIS (jeu de test 03_seed_test_data.sql / docs/test-data)
|
||||||
PersonalInfoData initialData;
|
PersonalInfoData initialData;
|
||||||
if (registrationData.firstName.isEmpty) {
|
if (registrationData.firstName.isEmpty) {
|
||||||
final genFirstName = DataGenerator.firstName();
|
|
||||||
final genLastName = DataGenerator.lastName();
|
|
||||||
initialData = PersonalInfoData(
|
initialData = PersonalInfoData(
|
||||||
firstName: genFirstName,
|
firstName: 'Marie',
|
||||||
lastName: genLastName,
|
lastName: 'DUBOIS',
|
||||||
phone: DataGenerator.phone(),
|
phone: '0696345678',
|
||||||
email: DataGenerator.email(genFirstName, genLastName),
|
email: 'marie.dubois@ptits-pas.fr',
|
||||||
address: DataGenerator.address(),
|
address: '25 Rue de la République',
|
||||||
postalCode: DataGenerator.postalCode(),
|
postalCode: '95870',
|
||||||
city: DataGenerator.city(),
|
city: 'Bezons',
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
initialData = PersonalInfoData(
|
initialData = PersonalInfoData(
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import 'dart:io';
|
|||||||
|
|
||||||
import '../../models/am_registration_data.dart';
|
import '../../models/am_registration_data.dart';
|
||||||
import '../../models/card_assets.dart';
|
import '../../models/card_assets.dart';
|
||||||
import '../../utils/data_generator.dart';
|
|
||||||
import '../../widgets/professional_info_form_screen.dart';
|
import '../../widgets/professional_info_form_screen.dart';
|
||||||
|
|
||||||
class AmRegisterStep2Screen extends StatefulWidget {
|
class AmRegisterStep2Screen extends StatefulWidget {
|
||||||
@ -54,17 +53,17 @@ class _AmRegisterStep2ScreenState extends State<AmRegisterStep2Screen> {
|
|||||||
capacity: registrationData.capacity,
|
capacity: registrationData.capacity,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Générer des données de test si les champs sont vides (NIR = Marie Dubois du seed, Corse 2A)
|
// Données de test : Marie DUBOIS (jeu de test 03_seed_test_data.sql / docs/test-data)
|
||||||
if (registrationData.dateOfBirth == null && registrationData.nir.isEmpty) {
|
if (registrationData.dateOfBirth == null && registrationData.nir.isEmpty) {
|
||||||
initialData = ProfessionalInfoData(
|
initialData = ProfessionalInfoData(
|
||||||
photoPath: 'assets/images/icon_assmat.png',
|
photoPath: 'assets/images/icon_assmat.png',
|
||||||
photoConsent: true,
|
photoConsent: true,
|
||||||
dateOfBirth: DateTime(1980, 6, 8),
|
dateOfBirth: DateTime(1980, 6, 8),
|
||||||
birthCity: 'Ajaccio',
|
birthCity: 'Bezons',
|
||||||
birthCountry: 'France',
|
birthCountry: 'France',
|
||||||
nir: '280062A00100191',
|
nir: '280062A00100191',
|
||||||
agrementNumber: 'AM${DataGenerator.randomIntInRange(10000, 100000)}',
|
agrementNumber: 'AGR-2019-095001',
|
||||||
capacity: DataGenerator.randomIntInRange(1, 5),
|
capacity: 4,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,12 +13,12 @@ class AmRegisterStep3Screen extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final data = Provider.of<AmRegistrationData>(context, listen: false);
|
final data = Provider.of<AmRegistrationData>(context, listen: false);
|
||||||
|
|
||||||
// Générer un texte de test si vide
|
// Données de test : Marie DUBOIS (jeu de test 03_seed_test_data.sql / docs/test-data)
|
||||||
String initialText = data.presentationText;
|
String initialText = data.presentationText;
|
||||||
bool initialCgu = data.cguAccepted;
|
bool initialCgu = data.cguAccepted;
|
||||||
|
|
||||||
if (initialText.isEmpty) {
|
if (initialText.isEmpty) {
|
||||||
initialText = 'Disponible immédiatement, plus de 10 ans d\'expérience avec les tout-petits. Formation aux premiers secours à jour. Je dispose d\'un jardin sécurisé et d\'un espace de jeu adapté.';
|
initialText = 'Assistante maternelle agréée depuis 2019. Spécialité bébés 0-18 mois. Accueil bienveillant et cadre sécurisant. 2 places disponibles.';
|
||||||
initialCgu = true;
|
initialCgu = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -56,6 +56,7 @@ class CustomAppTextField extends StatefulWidget {
|
|||||||
this.autofillHints,
|
this.autofillHints,
|
||||||
this.textInputAction,
|
this.textInputAction,
|
||||||
this.onFieldSubmitted,
|
this.onFieldSubmitted,
|
||||||
|
this.inputFormatters,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
19
scripts/README-create-issue.md
Normal file
19
scripts/README-create-issue.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Créer l’issue #84 (correctifs modale MDP) via l’API Gitea
|
||||||
|
|
||||||
|
1. Définir un token valide :
|
||||||
|
`export GITEA_TOKEN="votre_token"`
|
||||||
|
ou créer `.gitea-token` à la racine du projet avec le token seul.
|
||||||
|
|
||||||
|
2. Créer l’issue :
|
||||||
|
```bash
|
||||||
|
cd /chemin/vers/PetitsPas
|
||||||
|
curl -s -X POST \
|
||||||
|
-H "Authorization: token $GITEA_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d @scripts/issue-84-payload.json \
|
||||||
|
"https://git.ptits-pas.fr/api/v1/repos/jmartin/petitspas/issues"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. En cas de succès (HTTP 201), la réponse JSON contient le numéro de l’issue créée.
|
||||||
|
|
||||||
|
Payload utilisé : `scripts/issue-84-payload.json` (titre + corps depuis `scripts/issue-84-body.txt`).
|
||||||
51
scripts/create-gitea-issue.sh
Normal file
51
scripts/create-gitea-issue.sh
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Crée une issue Gitea via l'API.
|
||||||
|
# Usage: GITEA_TOKEN=xxx ./scripts/create-gitea-issue.sh
|
||||||
|
# Ou: mettre le token dans .gitea-token à la racine du projet.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
BASE_URL="${GITEA_URL:-https://git.ptits-pas.fr/api/v1}"
|
||||||
|
REPO="jmartin/petitspas"
|
||||||
|
|
||||||
|
if [ -z "$GITEA_TOKEN" ]; then
|
||||||
|
if [ -f .gitea-token ]; then
|
||||||
|
GITEA_TOKEN=$(cat .gitea-token)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$GITEA_TOKEN" ]; then
|
||||||
|
echo "Définir GITEA_TOKEN ou créer .gitea-token avec votre token Gitea."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
TITLE="$1"
|
||||||
|
BODY="$2"
|
||||||
|
if [ -z "$TITLE" ]; then
|
||||||
|
echo "Usage: $0 \"Titre de l'issue\" \"Corps (optionnel)\""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build JSON (escape body for JSON)
|
||||||
|
BODY_ESC=$(echo "$BODY" | jq -Rs . 2>/dev/null || echo "null")
|
||||||
|
if [ "$BODY_ESC" = "null" ] || [ -z "$BODY" ]; then
|
||||||
|
PAYLOAD=$(jq -n --arg t "$TITLE" '{title: $t}')
|
||||||
|
else
|
||||||
|
PAYLOAD=$(jq -n --arg t "$TITLE" --arg b "$BODY" '{title: $t, body: $b}')
|
||||||
|
fi
|
||||||
|
|
||||||
|
RESP=$(curl -s -w "\n%{http_code}" -X POST \
|
||||||
|
-H "Authorization: token $GITEA_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$PAYLOAD" \
|
||||||
|
"$BASE_URL/repos/$REPO/issues")
|
||||||
|
HTTP_CODE=$(echo "$RESP" | tail -1)
|
||||||
|
BODY_RESP=$(echo "$RESP" | sed '$d')
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" = "201" ]; then
|
||||||
|
ISSUE_NUM=$(echo "$BODY_RESP" | jq -r .number)
|
||||||
|
echo "Issue #$ISSUE_NUM créée."
|
||||||
|
echo "$BODY_RESP" | jq .
|
||||||
|
else
|
||||||
|
echo "Erreur HTTP $HTTP_CODE: $BODY_RESP"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
58
scripts/gitea-close-issue-with-comment.sh
Normal file
58
scripts/gitea-close-issue-with-comment.sh
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Poste un commentaire sur une issue Gitea puis la ferme.
|
||||||
|
# Usage: GITEA_TOKEN=xxx ./scripts/gitea-close-issue-with-comment.sh <numéro> "Commentaire"
|
||||||
|
# Ou: mettre le token dans .gitea-token à la racine du projet.
|
||||||
|
# Exemple: ./scripts/gitea-close-issue-with-comment.sh 15 "Livré : panneau Paramètres opérationnel."
|
||||||
|
|
||||||
|
set -e
|
||||||
|
ISSUE="${1:?Usage: $0 <numéro_issue> \"Commentaire\"}"
|
||||||
|
COMMENT="${2:?Usage: $0 <numéro_issue> \"Commentaire\"}"
|
||||||
|
BASE_URL="${GITEA_URL:-https://git.ptits-pas.fr/api/v1}"
|
||||||
|
REPO="jmartin/petitspas"
|
||||||
|
|
||||||
|
if [ -z "$GITEA_TOKEN" ]; then
|
||||||
|
if [ -f .gitea-token ]; then
|
||||||
|
GITEA_TOKEN=$(cat .gitea-token)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$GITEA_TOKEN" ]; then
|
||||||
|
echo "Définir GITEA_TOKEN ou créer .gitea-token avec votre token Gitea."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1) Poster le commentaire
|
||||||
|
echo "Ajout du commentaire sur l'issue #$ISSUE..."
|
||||||
|
# Échapper pour JSON (guillemets et backslash)
|
||||||
|
COMMENT_ESC=$(printf '%s' "$COMMENT" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\r//g')
|
||||||
|
PAYLOAD="{\"body\":\"$COMMENT_ESC\"}"
|
||||||
|
RESP=$(curl -s -w "\n%{http_code}" -X POST \
|
||||||
|
-H "Authorization: token $GITEA_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$PAYLOAD" \
|
||||||
|
"$BASE_URL/repos/$REPO/issues/$ISSUE/comments")
|
||||||
|
HTTP_CODE=$(echo "$RESP" | tail -1)
|
||||||
|
BODY=$(echo "$RESP" | sed '$d')
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" != "201" ]; then
|
||||||
|
echo "Erreur HTTP $HTTP_CODE lors du commentaire: $BODY"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Commentaire ajouté."
|
||||||
|
|
||||||
|
# 2) Fermer l'issue
|
||||||
|
echo "Fermeture de l'issue #$ISSUE..."
|
||||||
|
RESP2=$(curl -s -w "\n%{http_code}" -X PATCH \
|
||||||
|
-H "Authorization: token $GITEA_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"state":"closed"}' \
|
||||||
|
"$BASE_URL/repos/$REPO/issues/$ISSUE")
|
||||||
|
HTTP_CODE2=$(echo "$RESP2" | tail -1)
|
||||||
|
BODY2=$(echo "$RESP2" | sed '$d')
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE2" = "200" ] || [ "$HTTP_CODE2" = "201" ]; then
|
||||||
|
echo "Issue #$ISSUE fermée."
|
||||||
|
else
|
||||||
|
echo "Erreur HTTP $HTTP_CODE2: $BODY2"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
14
scripts/issue-84-body.txt
Normal file
14
scripts/issue-84-body.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
Correctifs et améliorations de la modale de changement de mot de passe obligatoire affichée à la première connexion admin.
|
||||||
|
|
||||||
|
**Périmètre :**
|
||||||
|
- Ajustements visuels / UX de la modale (ChangePasswordDialog)
|
||||||
|
- Cohérence charte graphique, espacements, lisibilité
|
||||||
|
- Comportement (validation, messages d'erreur, fermeture)
|
||||||
|
- Lien de test en debug sur l'écran login (« Test modale MDP ») pour faciliter les réglages
|
||||||
|
|
||||||
|
**Tâches :**
|
||||||
|
- [ ] Revoir le design de la modale (relief, bordures, couleurs)
|
||||||
|
- [ ] Vérifier les champs (MDP actuel, nouveau, confirmation) et validations
|
||||||
|
- [ ] Ajuster les textes et messages d'erreur
|
||||||
|
- [ ] Tester sur mobile et desktop
|
||||||
|
- [ ] Retirer ou conditionner le lien « Test modale MDP » en production si besoin
|
||||||
1
scripts/issue-84-payload.json
Normal file
1
scripts/issue-84-payload.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"title": "[Frontend] Bug – Correctifs modale Changement MDP (première connexion admin)", "body": "Correctifs et améliorations de la modale de changement de mot de passe obligatoire affichée à la première connexion admin.\n\n**Périmètre :**\n- Ajustements visuels / UX de la modale (ChangePasswordDialog)\n- Cohérence charte graphique, espacements, lisibilité\n- Comportement (validation, messages d'erreur, fermeture)\n- Lien de test en debug sur l'écran login (« Test modale MDP ») pour faciliter les réglages\n\n**Tâches :**\n- [ ] Revoir le design de la modale (relief, bordures, couleurs)\n- [ ] Vérifier les champs (MDP actuel, nouveau, confirmation) et validations\n- [ ] Ajuster les textes et messages d'erreur\n- [ ] Tester sur mobile et desktop\n- [ ] Retirer ou conditionner le lien « Test modale MDP » en production si besoin\n"}
|
||||||
Loading…
x
Reference in New Issue
Block a user