guidesoutenance

This commit is contained in:
2026-09-30 08:24:20 +02:00
parent 4de305bbf4
commit 07f88198c0
21 changed files with 1067 additions and 331 deletions

View File

@@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_appauth/flutter_appauth.dart';
@@ -6,6 +7,7 @@ import '../config/intra_config.dart';
import '../services/intra_api_exception.dart';
import '../services/intra_auth_service.dart';
import '../services/intra_user_service.dart';
import '../theme/swifty_ui.dart';
import 'profile_screen.dart';
/// Vue 1 — recherche par login 42.
@@ -106,9 +108,9 @@ class _SearchScreenState extends State<SearchScreen> {
Widget build(BuildContext context) {
if (!IntraConfig.isConfigured) {
return Scaffold(
appBar: AppBar(title: const Text('Swifty Companion')),
body: const Padding(
padding: EdgeInsets.all(24),
appBar: SwiftyUi.appBar(title: 'Swifty Companion'),
body: const ResponsiveScrollBody(
maxWidth: SwiftyUi.searchMaxWidth,
child: Text(
'Fichier .env manquant dans swifty_companion/.env',
),
@@ -117,55 +119,50 @@ class _SearchScreenState extends State<SearchScreen> {
}
final isAuthenticated = _auth.isAuthenticated;
final busy = _connecting || _searching;
return Scaffold(
appBar: AppBar(
title: const Text('Swifty Companion'),
backgroundColor: const Color(0xFF00BABC),
foregroundColor: Colors.black,
appBar: SwiftyUi.appBar(
title: 'Swifty Companion',
actions: [
if (isAuthenticated)
IconButton(
onPressed: _connecting || _searching ? null : _disconnect,
onPressed: busy ? null : _disconnect,
icon: const Icon(Icons.logout),
tooltip: 'Déconnexion API',
),
],
),
body: Padding(
padding: const EdgeInsets.all(24),
body: ResponsiveScrollBody(
maxWidth: SwiftyUi.searchMaxWidth,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (!isAuthenticated) ...[
const Text(
Text(
'Connexion API 42',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
const Text(
Text(
'Connecte-toi une fois ; le token servira pour toutes les recherches.',
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: 16),
FilledButton(
onPressed: _connecting ? null : _connect,
child: _connecting
? const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text('Se connecter avec 42'),
const SizedBox(height: 20),
LoadingFilledButton(
label: 'Se connecter avec 42',
loading: _connecting,
onPressed: _connect,
),
] else ...[
Text(
'Session : ${_sessionLogin ?? 'connecté'}',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 24),
const Text(
const SizedBox(height: 28),
Text(
'Rechercher un étudiant',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 12),
TextField(
@@ -176,29 +173,40 @@ class _SearchScreenState extends State<SearchScreen> {
border: OutlineInputBorder(),
),
textInputAction: TextInputAction.search,
autocorrect: false,
enableSuggestions: false,
onSubmitted: (_) {
if (!_searching) _search();
},
enabled: !_searching,
),
const SizedBox(height: 16),
FilledButton(
onPressed: _searching ? null : _search,
child: _searching
? const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text('Rechercher'),
LoadingFilledButton(
label: 'Rechercher',
loading: _searching,
onPressed: _search,
),
if (kDebugMode) ...[
const SizedBox(height: 12),
TextButton(
onPressed: _auth.canRefresh
? () {
_auth.debugInvalidateAccessToken();
setState(() {
_error =
'DEBUG : access token invalidé (refresh conservé). '
'Étape suivante : saisis un login et appuie sur « Rechercher ». '
'Si le bonus marche, le profil s’ouvre sans repasser par OAuth 42.';
});
}
: null,
child: const Text('DEBUG : simuler token expiré'),
),
],
],
if (_error != null) ...[
const SizedBox(height: 16),
Text(
_error!,
style: TextStyle(color: Theme.of(context).colorScheme.error),
),
const SizedBox(height: 20),
ErrorMessage(message: _error!),
],
],
),