import 'dart:async'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:flutter/foundation.dart' show kIsWeb; class LoginPage extends StatelessWidget { const LoginPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.transparent, body: LayoutBuilder( builder: (context, constraints) { // Version desktop (web) if (kIsWeb) { final w = constraints.maxWidth; final h = constraints.maxHeight; return FutureBuilder( future: _getImageDimensions(), builder: (context, snapshot) { if (!snapshot.hasData) { return const Center(child: CircularProgressIndicator()); } final imageDimensions = snapshot.data!; final imageHeight = h; final imageWidth = imageHeight * (imageDimensions.width / imageDimensions.height); final remainingWidth = w - imageWidth; final leftMargin = remainingWidth / 4; return Stack( children: [ // Fond en papier Positioned.fill( child: Image.asset( 'assets/images/paper2.png', fit: BoxFit.cover, repeat: ImageRepeat.repeat, ), ), // Image principale Positioned( left: leftMargin, top: 0, height: imageHeight, width: imageWidth, child: Image.asset( 'assets/images/river_logo_desktop.png', fit: BoxFit.contain, ), ), // Formulaire Positioned( left: leftMargin + imageWidth + (remainingWidth - leftMargin) / 2 - 200, top: h * 0.3, child: Column( mainAxisSize: MainAxisSize.min, children: [ // Champ email _ImageTextField( bg: 'assets/images/field_email.png', width: 400, height: 80, hint: 'Email', ), const SizedBox(height: 20), // Champ mot de passe _ImageTextField( bg: 'assets/images/field_password.png', width: 400, height: 80, hint: 'Mot de passe', obscure: true, ), const SizedBox(height: 30), // Bouton de connexion _ImageButton( bg: 'assets/images/btn_green.png', width: 400, height: 80, text: 'Se connecter', onPressed: () { // TODO: Implémenter la logique de connexion }, ), ], ), ), ], ); }, ); } // Version mobile (à implémenter) return const Center( child: Text('Version mobile à implémenter'), ); }, ), ); } Future _getImageDimensions() async { final image = Image.asset('assets/images/river_logo_desktop.png'); final completer = Completer(); image.image.resolve(const ImageConfiguration()).addListener( ImageStreamListener((info, _) { completer.complete(ImageDimensions( width: info.image.width.toDouble(), height: info.image.height.toDouble(), )); }), ); return completer.future; } } class ImageDimensions { final double width; final double height; ImageDimensions({required this.width, required this.height}); } // ─────────────────────────────────────────────────────────────── // Champ texte avec fond image // ─────────────────────────────────────────────────────────────── class _ImageTextField extends StatelessWidget { final String bg; final double width; final double height; final String hint; final bool obscure; const _ImageTextField({ required this.bg, required this.width, required this.height, required this.hint, this.obscure = false, }); @override Widget build(BuildContext context) { return SizedBox( width: width, height: height, child: Stack( children: [ Positioned.fill(child: Image.asset(bg, fit: BoxFit.fill)), TextField( obscureText: obscure, style: GoogleFonts.merienda(fontSize: width * 0.045), decoration: InputDecoration( border: InputBorder.none, hintText: hint, hintStyle: GoogleFonts.merienda( fontSize: width * 0.045, color: Colors.black54, ), contentPadding: EdgeInsets.symmetric( horizontal: width * 0.07, // 7 % latéral vertical: height * 0.22, // 22 % vertical ), ), ), ], ), ); } } // ─────────────────────────────────────────────────────────────── // Bouton avec fond image // ─────────────────────────────────────────────────────────────── class _ImageButton extends StatelessWidget { final String bg; final double width; final double height; final String text; final VoidCallback onPressed; const _ImageButton({ required this.bg, required this.width, required this.height, required this.text, required this.onPressed, }); @override Widget build(BuildContext context) { return SizedBox( width: width, height: height, child: Material( color: Colors.transparent, child: InkWell( onTap: onPressed, child: Stack( children: [ Positioned.fill(child: Image.asset(bg, fit: BoxFit.fill)), Center( child: Text( text, style: GoogleFonts.merienda( fontSize: width * 0.045, color: Colors.white, ), ), ), ], ), ), ), ); } }