guidesoutenance
This commit is contained in:
@@ -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!),
|
||||
],
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user