From 1b04d66de9c9c7f7814c445e0dc25cac619ea2c9 Mon Sep 17 00:00:00 2001 From: sartron_Northblue Date: Fri, 12 Sep 2025 13:51:10 +0400 Subject: [PATCH] ajout de la box avec le profil + la barre de recherche --- README.md | 71 ++++++-- assets/images/fond1.webp | Bin 0 -> 18442 bytes lib/main.dart | 120 +++---------- lib/theme/app_theme.dart | 122 +++++++++++++ lib/widgets/header_widget.dart | 68 ++++++++ lib/widgets/hero_section_widget.dart | 252 +++++++++++++++++++++++++++ lib/widgets/search_bar_widget.dart | 56 ++++++ 7 files changed, 581 insertions(+), 108 deletions(-) create mode 100644 assets/images/fond1.webp create mode 100644 lib/theme/app_theme.dart create mode 100644 lib/widgets/header_widget.dart create mode 100644 lib/widgets/hero_section_widget.dart create mode 100644 lib/widgets/search_bar_widget.dart diff --git a/README.md b/README.md index c43db62..041de39 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,67 @@ -# web +# Travel Discovery App -A new Flutter project. +Une application Flutter moderne pour découvrir des destinations de voyage, inspirée d'un design élégant et moderne. -## Getting Started +## 🎨 Fonctionnalités -This project is a starting point for a Flutter application. +- **Interface moderne** : Design épuré avec des gradients et des ombres +- **Header personnalisé** : Profil utilisateur avec notifications +- **Section Hero** : Affichage spectaculaire du volcan Arenal avec effet de lave +- **Barre de recherche** : Interface intuitive pour rechercher des destinations +- **Thème personnalisé** : Couleurs et typographies cohérentes -A few resources to get you started if this is your first Flutter project: +## 🚀 Installation -- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) +1. Assurez-vous d'avoir Flutter installé sur votre machine +2. Clonez ce repository +3. Naviguez vers le dossier du projet +4. Installez les dépendances : + ```bash + flutter pub get + ``` -For help getting started with Flutter development, view the -[online documentation](https://docs.flutter.dev/), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +## 🏃‍♂️ Lancement + +Pour lancer l'application : + +```bash +flutter run +``` + +Pour lancer sur le web : +```bash +flutter run -d chrome +``` + +## 📱 Structure du projet + +``` +lib/ +├── main.dart # Point d'entrée de l'application +├── theme/ +│ └── app_theme.dart # Thème personnalisé avec couleurs et styles +└── widgets/ + ├── header_widget.dart # Widget du header avec profil utilisateur + ├── hero_section_widget.dart # Widget de la section hero avec le volcan + └── search_bar_widget.dart # Widget de la barre de recherche +``` + +## 🎨 Design + +L'application utilise : +- **Couleurs** : Palette orange/rouge pour évoquer la lave du volcan +- **Gradients** : Effets visuels pour simuler l'éruption volcanique +- **Typographie** : Police moderne et lisible +- **Ombres** : Effets de profondeur pour un design moderne + +## 🔧 Personnalisation + +Vous pouvez facilement personnaliser : +- Les couleurs dans `lib/theme/app_theme.dart` +- Les textes dans les widgets +- Les gradients pour créer d'autres effets visuels +- Les icônes et les images + +## 📄 Licence + +Ce projet est sous licence MIT. \ No newline at end of file diff --git a/assets/images/fond1.webp b/assets/images/fond1.webp new file mode 100644 index 0000000000000000000000000000000000000000..e31c0cb55125fc100c52d8b7a137c35f2a294c5b GIT binary patch literal 18442 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 xE$1pq=Ku createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } +class TravelHomePage extends StatelessWidget { + const TravelHomePage({super.key}); @override Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. return Scaffold( - appBar: AppBar( - // TRY THIS: Try changing the color here to a specific color (to - // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar - // change color while the other colors stay the same. - backgroundColor: Theme.of(context).colorScheme.inversePrimary, - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. + backgroundColor: AppTheme.backgroundColor, + body: SafeArea( child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - // - // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" - // action in the IDE, or press "p" in the console), to see the - // wireframe for each widget. - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text('You have pushed the button this many times:'), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, + children: [ + SizedBox( + height: MediaQuery.of(context).size.height * 0.5, + child: const HeroSectionWidget(), ), + + const SizedBox(height: 20), ], ), ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. ); } -} + +} \ No newline at end of file diff --git a/lib/theme/app_theme.dart b/lib/theme/app_theme.dart new file mode 100644 index 0000000..0481604 --- /dev/null +++ b/lib/theme/app_theme.dart @@ -0,0 +1,122 @@ +import 'package:flutter/material.dart'; + +class AppTheme { + static const Color primaryColor = Color(0xFFFF6B35); + static const Color secondaryColor = Color(0xFF2C3E50); + static const Color backgroundColor = Color(0xFFF8F9FA); + static const Color cardColor = Colors.white; + static const Color textPrimary = Color(0xFF2C3E50); + static const Color textSecondary = Color(0xFF7F8C8D); + static const Color accentColor = Color(0xFFFFA726); + + static ThemeData get lightTheme { + return ThemeData( + useMaterial3: true, + colorScheme: ColorScheme.fromSeed( + seedColor: primaryColor, + brightness: Brightness.light, + ), + scaffoldBackgroundColor: backgroundColor, + appBarTheme: const AppBarTheme( + backgroundColor: Colors.transparent, + elevation: 0, + iconTheme: IconThemeData(color: textPrimary), + titleTextStyle: TextStyle( + color: textPrimary, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + textTheme: const TextTheme( + headlineLarge: TextStyle( + fontSize: 32, + fontWeight: FontWeight.bold, + color: Colors.white, + height: 1.1, + ), + headlineMedium: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: textPrimary, + ), + titleLarge: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: textPrimary, + ), + titleMedium: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: textPrimary, + ), + bodyLarge: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: textPrimary, + ), + bodyMedium: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + color: textSecondary, + ), + bodySmall: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w400, + color: textSecondary, + ), + ), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + backgroundColor: primaryColor, + foregroundColor: Colors.white, + elevation: 4, + shadowColor: primaryColor.withOpacity(0.3), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), + ), + ), + cardTheme: CardThemeData( + color: cardColor, + elevation: 8, + shadowColor: Colors.black.withOpacity(0.1), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + ), + ); + } + + // Gradients personnalisés + static const LinearGradient volcanoGradient = LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Color(0xFF1A1A1A), // Ciel sombre + Color(0xFF2D1B1B), // Rouge sombre + Color(0xFF8B0000), // Rouge foncé (lave) + Color(0xFFFF4500), // Rouge-orange (lave chaude) + Color(0xFFFF6347), // Orange (lave) + Color(0xFF4169E1), // Bleu ciel + Color(0xFF87CEEB), // Bleu clair + ], + stops: [0.0, 0.2, 0.4, 0.5, 0.6, 0.8, 1.0], + ); + + static const LinearGradient profileGradient = LinearGradient( + colors: [Color(0xFFFFB74D), Color(0xFFFF6B35)], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ); + + static const LinearGradient cardGradient = LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Color(0xFF1A1A2E), + Color(0xFF16213E), + Color(0xFF0F3460), + ], + ); +} diff --git a/lib/widgets/header_widget.dart b/lib/widgets/header_widget.dart new file mode 100644 index 0000000..ae572c3 --- /dev/null +++ b/lib/widgets/header_widget.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import '../theme/app_theme.dart'; + +class HeaderWidget extends StatelessWidget { + const HeaderWidget({super.key}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), + child: Row( + children: [ + Container( + width: 50, + height: 50, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: AppTheme.profileGradient, + ), + child: const Icon( + Icons.person, + color: Colors.white, + size: 28, + ), + ), + + const SizedBox(width: 16), + + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Welcome Back', + style: Theme.of(context).textTheme.bodyMedium, + ), + Text( + 'John Anon', + style: Theme.of(context).textTheme.titleLarge, + ), + ], + ), + ), + Container( + width: 44, + height: 44, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(22), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 8, + offset: const Offset(0, 2), + ), + ], + ), + child: const Icon( + Icons.notifications_outlined, + color: Colors.black54, + size: 24, + ), + ), + ], + ), + ); + } +} diff --git a/lib/widgets/hero_section_widget.dart b/lib/widgets/hero_section_widget.dart new file mode 100644 index 0000000..a98e0ff --- /dev/null +++ b/lib/widgets/hero_section_widget.dart @@ -0,0 +1,252 @@ +import 'package:flutter/material.dart'; +import '../theme/app_theme.dart'; + +class HeroSectionWidget extends StatelessWidget { + const HeroSectionWidget({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + margin: const EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + gradient: AppTheme.cardGradient, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.3), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Stack( + children: [ + Positioned.fill( + child: ClipRRect( + borderRadius: BorderRadius.circular(24), + child: Image.asset( + 'assets/images/fond1.webp', + fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) { + return Container( + decoration: BoxDecoration( + gradient: AppTheme.volcanoGradient, + ), + ); + }, + ), + ), + ), + Positioned.fill( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + gradient: RadialGradient( + center: const Alignment(0.3, -0.4), + radius: 0.8, + colors: [ + Colors.transparent, + Colors.transparent, + const Color(0xFFFF4500).withOpacity(0.3), + const Color(0xFFFF6347).withOpacity(0.2), + Colors.transparent, + ], + stops: const [0.0, 0.3, 0.5, 0.7, 1.0], + ), + ), + ), + ), + Positioned.fill( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.transparent, + Colors.black.withOpacity(0.7), + ], + ), + ), + ), + ), + Positioned( + top: 20, + left: 20, + right: 20, + child: Row( + children: [ + Container( + width: 50, + height: 50, + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: AppTheme.profileGradient, + ), + child: const Icon( + Icons.person, + color: Colors.white, + size: 28, + ), + ), + + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Welcome Back', + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: Colors.white.withOpacity(0.8), + ), + ), + Text( + 'John Anon', + style: Theme.of(context).textTheme.titleLarge?.copyWith( + color: Colors.white, + ), + ), + ], + ), + ), + Container( + width: 44, + height: 44, + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.2), + borderRadius: BorderRadius.circular(22), + border: Border.all( + color: Colors.white.withOpacity(0.3), + width: 1, + ), + ), + child: const Icon( + Icons.notifications_outlined, + color: Colors.white, + size: 24, + ), + ), + ], + ), + ), + Positioned( + bottom: 80, + left: 24, + right: 24, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + const Icon( + Icons.location_on, + color: Colors.white, + size: 16, + ), + const SizedBox(width: 4), + const Text( + 'dans mon ventre', + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + + const SizedBox(height: 8), + Text( + 'Notre poisson rouge', + style: Theme.of(context).textTheme.headlineLarge, + ), + + const SizedBox(height: 8), + Row( + children: [ + const Icon( + Icons.star, + color: AppTheme.accentColor, + size: 18, + ), + const SizedBox(width: 4), + const Text( + '4/5', + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(width: 8), + Text( + '(500+ Review)', + style: TextStyle( + color: Colors.white.withOpacity(0.8), + fontSize: 14, + fontWeight: FontWeight.w400, + ), + ), + ], + ), + ], + ), + ), + Positioned( + bottom: 20, + left: 8, + right: 8, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 4), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.9), + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 10, + offset: const Offset(0, 4), + ), + ], + ), + child: Row( + children: [ + Icon( + Icons.search, + color: AppTheme.textSecondary, + size: 24, + ), + const SizedBox(width: 12), + Expanded( + child: Text( + 'Search your destination...', + style: Theme.of(context).textTheme.bodyLarge?.copyWith( + color: AppTheme.textSecondary, + ), + ), + ), + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: Colors.grey.shade100, + borderRadius: BorderRadius.circular(12), + ), + child: Icon( + Icons.tune, + color: AppTheme.textSecondary, + size: 20, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/widgets/search_bar_widget.dart b/lib/widgets/search_bar_widget.dart new file mode 100644 index 0000000..75f8eca --- /dev/null +++ b/lib/widgets/search_bar_widget.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; +import '../theme/app_theme.dart'; + +class SearchBarWidget extends StatelessWidget { + const SearchBarWidget({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.symmetric(horizontal: 8), + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 4), + decoration: BoxDecoration( + color: AppTheme.cardColor, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 10, + offset: const Offset(0, 4), + ), + ], + ), + child: Row( + children: [ + Icon( + Icons.search, + color: AppTheme.textSecondary, + size: 24, + ), + const SizedBox(width: 12), + Expanded( + child: Text( + 'Search your destination...', + style: Theme.of(context).textTheme.bodyLarge?.copyWith( + color: AppTheme.textSecondary, + ), + ), + ), + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: Colors.grey.shade100, + borderRadius: BorderRadius.circular(12), + ), + child: Icon( + Icons.tune, + color: AppTheme.textSecondary, + size: 20, + ), + ), + ], + ), + ); + } +}