sheet_view_page.dart 7,75 ko
Newer Older
import 'package:flutter/material.dart';
import 'google_sheets_api.dart';

class SheetViewPage extends StatefulWidget {
  const SheetViewPage({super.key});

  @override
  State<SheetViewPage> createState() => _SheetViewPageState();
}

class _SheetViewPageState extends State<SheetViewPage> {
  final GoogleSheetsApi _api = GoogleSheetsApi();
  List<List<dynamic>> _rows = [];
  bool _loading = false;
mouhamed lamine kebe's avatar
mouhamed lamine kebe a validé
  final Color _primaryColor = const Color(0xFF4361EE);

  @override
  void initState() {
    super.initState();
    _load();
  }

  Future<void> _load() async {
    setState(() => _loading = true);
    final data = await _api.readData();
    print('Données chargées : $data');
    setState(() {
      _rows = data ?? [];
      _loading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
mouhamed lamine kebe's avatar
mouhamed lamine kebe a validé
      backgroundColor: const Color(0xFFF8F9FA),
mouhamed lamine kebe's avatar
mouhamed lamine kebe a validé
        title: const Text(
          'Liste des Étudiants',
          style: TextStyle(fontWeight: FontWeight.bold),
        ),
        backgroundColor: _primaryColor,
        foregroundColor: Colors.white,
        elevation: 0,
mouhamed lamine kebe's avatar
mouhamed lamine kebe a validé
            icon: const Icon(Icons.refresh_rounded),
mouhamed lamine kebe's avatar
mouhamed lamine kebe a validé
            tooltip: 'Actualiser',
mouhamed lamine kebe's avatar
mouhamed lamine kebe a validé
          ? const Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            CircularProgressIndicator(),
            SizedBox(height: 16),
            Text(
              'Chargement des données...',
              style: TextStyle(fontSize: 16, color: Colors.grey),
            ),
          ],
        ),
      )
mouhamed lamine kebe's avatar
mouhamed lamine kebe a validé
          ? Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(
              Icons.table_chart_outlined,
              size: 80,
              color: Colors.grey.shade300,
            ),
            const SizedBox(height: 16),
            const Text(
              'Aucune donnée trouvée',
              style: TextStyle(fontSize: 18, color: Colors.grey),
            ),
            const SizedBox(height: 8),
            Text(
              'Les données apparaitront ici après inscription',
              style: TextStyle(fontSize: 14, color: Colors.grey.shade500),
              textAlign: TextAlign.center,
            ),
          ],
        ),
      )
          : Padding(
        padding: const EdgeInsets.all(16),
        child: Card(
          elevation: 4,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(16),
          ),
          child: Column(
            children: [
              // En-tête du tableau
              Container(
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: _primaryColor.withOpacity(0.1),
                  borderRadius: const BorderRadius.only(
                    topLeft: Radius.circular(16),
                    topRight: Radius.circular(16),
                  ),
                ),
                child: Row(
                  children: [
                    Icon(Icons.table_chart_rounded, color: _primaryColor),
                    const SizedBox(width: 12),
                    Text(
                      '${_rows.length} étudiant(s) inscrit(s)',
                      style: const TextStyle(
                        fontSize: 16,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const Spacer(),
                    Chip(
                      label: Text('${_rows.length} éléments'),
                      backgroundColor: _primaryColor,
                      labelStyle: const TextStyle(color: Colors.white),
                    ),
                  ],
                ),
              ),

              // Liste des données
              Expanded(
                child: ListView.separated(
mouhamed lamine kebe's avatar
mouhamed lamine kebe a validé
                  separatorBuilder: (context, index) => Divider(
                    height: 1,
                    color: Colors.grey.shade200,
                  ),
                  itemBuilder: (context, index) {
                    final row = _rows[index];
mouhamed lamine kebe's avatar
mouhamed lamine kebe a validé
                    return Container(
                      decoration: BoxDecoration(
                        color: index.isEven
                            ? Colors.white
                            : Colors.grey.withOpacity(0.02),
                      ),
                      child: ListTile(
                        leading: Container(
                          width: 40,
                          height: 40,
                          decoration: BoxDecoration(
                            color: _primaryColor.withOpacity(0.1),
                            shape: BoxShape.circle,
                          ),
                          child: Icon(
                            Icons.person_rounded,
                            color: _primaryColor,
                            size: 20,
                          ),
                        ),
                        title: Text(
                          '${row.length > 1 ? '${row[1]} ${row[2]}' : 'Étudiant ${index + 1}'}',
                          style: const TextStyle(
                            fontWeight: FontWeight.w500,
                          ),
                        ),
                        subtitle: row.length > 0
                            ? Text(
                          'N°: ${row[0]?.toString() ?? 'N/A'}',
                          style: TextStyle(
                            color: Colors.grey.shade600,
                          ),
                        )
                            : null,
                        trailing: Icon(
                          Icons.chevron_right_rounded,
                          color: Colors.grey.shade400,
                        ),
                        onTap: () {
                          // Optionnel: Ajouter une vue détaillée
                          showDialog(
                            context: context,
                            builder: (context) => AlertDialog(
                              title: const Text('Détails de l\'étudiant'),
                              content: SingleChildScrollView(
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: row.asMap().entries.map((entry) {
                                    return Padding(
                                      padding: const EdgeInsets.symmetric(vertical: 4),
                                      child: Text(
                                        '${_getColumnName(entry.key)}: ${entry.value?.toString() ?? 'N/A'}',
                                      ),
                                    );
                                  }).toList(),
                                ),
                              ),
                              actions: [
                                TextButton(
                                  onPressed: () => Navigator.of(context).pop(),
                                  child: const Text('Fermer'),
                                ),
                              ],
                            ),
                          );
                        },
                      ),
mouhamed lamine kebe's avatar
mouhamed lamine kebe a validé

  String _getColumnName(int index) {
    const columns = [
      'Numéro étudiant',
      'Prénom',
      'Nom',
      'MAC',
      'NFC',
      'QR Code',
      'Date d\'inscription'
    ];
    return index < columns.length ? columns[index] : 'Colonne $index';
  }
}