diff --git a/lib/classes/contactClass.dart b/lib/classes/contactClass.dart new file mode 100644 index 0000000..3d7dd91 --- /dev/null +++ b/lib/classes/contactClass.dart @@ -0,0 +1,9 @@ +// Create contact lists +class Contact { + final String name; + final String phoneNumber; + final bool isFavorite; + final bool isLocked; + + Contact(this.name, this.phoneNumber, {this.isFavorite = false, this.isLocked = false}); +} diff --git a/lib/classes/displayAvatar.dart b/lib/classes/displayAvatar.dart new file mode 100644 index 0000000..f5cacb9 --- /dev/null +++ b/lib/classes/displayAvatar.dart @@ -0,0 +1,29 @@ +import 'package:dialer/classes/contactClass.dart'; +import 'package:flutter/material.dart'; + +class DisplayAvatar extends StatelessWidget { + final Contact contact; + + const DisplayAvatar({super.key, required this.contact}); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + CircleAvatar( + child: Text(contact.name[0]), + ), + if (contact.isLocked) + const Positioned( + right: 0, + bottom: 0, + child: Icon( + Icons.lock, + color: Colors.white, + size: 20.0, + ), + ), + ], + ); + } +} diff --git a/lib/classes/displayContact.dart b/lib/classes/displayContact.dart new file mode 100644 index 0000000..292ae97 --- /dev/null +++ b/lib/classes/displayContact.dart @@ -0,0 +1,47 @@ +import 'package:dialer/pages/callingPage.dart'; +import 'package:dialer/classes/contactClass.dart'; +import 'package:dialer/classes/displayAvatar.dart'; +import 'package:dialer/pages/history.dart'; +import 'package:flutter/material.dart'; + + +class DisplayContact extends StatelessWidget { + String getTimeElapsed(DateTime date) { + final now = DateTime.now(); + final difference = now.difference(date); + if (difference.inDays > 0) { + return '${difference.inDays} days ago'; + } else if (difference.inHours > 0) { + return '${difference.inHours} hours ago'; + } else if (difference.inMinutes > 0) { + return '${difference.inMinutes} minutes ago'; + } else { + return 'Just now'; + } + } + + final Contact contact; + final History? history; + + const DisplayContact({super.key, required this.contact, this.history}); + + void _openVisualPage(BuildContext context) { + Navigator.push(context, MaterialPageRoute(builder: (context) => CallingPage(contact: contact))); + } + + @override + Widget build(BuildContext context) { + return ListTile( + leading: DisplayAvatar(contact: contact), + title: Text(contact.name), + subtitle: history != null ? Text(getTimeElapsed(history!.date)) : null, + trailing: InkWell( + onTap: () => _openVisualPage(context), + child: const Icon(Icons.call), + ), + onTap: () { + // Ajoutez ici le code pour appeler le contact + }, + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index 7add0ba..27e3df6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,9 +1,10 @@ // This is DEV +import 'package:dialer/pages/myHomePage.dart'; import 'package:flutter/material.dart'; void main() { - runApp(MyApp()); + runApp(const MyApp()); } class MyApp extends StatelessWidget { @@ -15,354 +16,7 @@ class MyApp extends StatelessWidget { theme: ThemeData( brightness: Brightness.dark ), - home: MyHomePage(), + home: const MyHomePage(), ); } } - -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key}); - - @override - _MyHomePageState createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State with SingleTickerProviderStateMixin { - late TabController _tabController; - - @override - void initState() { - super.initState(); - _tabController = TabController(length: 3, vsync: this, initialIndex: 1); - _tabController.addListener(_handleTabIndex); - } - - @override - void dispose() { - _tabController.removeListener(_handleTabIndex); - _tabController.dispose(); - super.dispose(); - } - - void _handleTabIndex() { - setState(() {}); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar( - // backgroundColor: Colors.black, - // foregroundColor: Colors.black, - // // title: const Text('Barre de navigation inférieure'), - // ), - backgroundColor: Colors.black, - body: TabBarView( - controller: _tabController, - children: [ - FavoritePage(), // Page des favoris - HistoryPage(), // Page de l'historique - ContactPage(), // Page des contacts - ], - ), - bottomNavigationBar: Container( - color: Colors.black, - child: TabBar( - controller: _tabController, - tabs: [ - Tab(icon: Icon(_tabController.index == 0 ? Icons.star : Icons.star_border)), - Tab(icon: Icon(_tabController.index == 1 ? Icons.access_time_filled : Icons.access_time_outlined)), - Tab(icon: Icon(_tabController.index == 2 ? Icons.contacts : Icons.contacts_outlined)), - ], - labelColor: Colors.white, - unselectedLabelColor: Colors.grey, - indicatorSize: TabBarIndicatorSize.label, - indicatorPadding: const EdgeInsets.only(bottom: -0), // Ajustez le padding pour élever la ligne blanche au-dessus des icônes si nécessaire - indicatorColor: Colors.white, // Couleur de la barre horizontale blanche - ), - ), - ); - } -} - -class ContactPage extends StatefulWidget { - const ContactPage({super.key}); - - @override - _ContactPageState createState() => _ContactPageState(); -} - -class _ContactPageState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.black, - appBar: AppBar( - title: const Text('Contacts'), - ), - body: ListView.builder( - itemCount: contacts.length, - itemBuilder: (context, index) { - return DisplayContact(contact: contacts[index]); - }, - ), - ); - } -} - -class FavoritePage extends StatefulWidget { - const FavoritePage({super.key}); - - @override - _FavoritePageState createState() => _FavoritePageState(); -} - -class _FavoritePageState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.black, - appBar: AppBar( - title: const Text('Favorites'), - ), - body: ListView.builder( - itemCount: contacts.length, - itemBuilder: (context, index) { - if (contacts[index].isFavorite) { - return DisplayContact(contact: contacts[index]); - } else { - return const SizedBox.shrink(); - } - }, - ), - ); - } -} - -class HistoryPage extends StatefulWidget { - const HistoryPage({super.key}); - - @override - _HistoryPageState createState() => _HistoryPageState(); -} - -class _HistoryPageState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.black, - appBar: AppBar( - title: const Text('History'), - ), - body: ListView.builder( - itemCount: histories.length, - itemBuilder: (context, index) { - return DisplayContact(contact: histories[index].contact, history: histories[index]); - }, - ), - ); - } -} - -class DisplayContact extends StatelessWidget { - String getTimeElapsed(DateTime date) { - final now = DateTime.now(); - final difference = now.difference(date); - if (difference.inDays > 0) { - return '${difference.inDays} days ago'; - } else if (difference.inHours > 0) { - return '${difference.inHours} hours ago'; - } else if (difference.inMinutes > 0) { - return '${difference.inMinutes} minutes ago'; - } else { - return 'Just now'; - } - } - - final Contact contact; - final History? history; - - const DisplayContact({super.key, required this.contact, this.history}); - - void _openVisualPage(BuildContext context) { - Navigator.push(context, MaterialPageRoute(builder: (context) => CallingPage(contact: contact))); - } - - @override - Widget build(BuildContext context) { - return ListTile( - leading: DisplayAvatar(contact: contact), - title: Text(contact.name), - subtitle: history != null ? Text(getTimeElapsed(history!.date)) : null, - trailing: InkWell( - onTap: () => _openVisualPage(context), - child: const Icon(Icons.call), - ), - onTap: () { - // Ajoutez ici le code pour appeler le contact - }, - ); - } -} - -class CallingPage extends StatefulWidget { - final Contact contact; - - const CallingPage({super.key, required this.contact}); - - @override - _CallingPageState createState() => _CallingPageState(); -} - -// display the calling page as if the call is already in progress -class _CallingPageState extends State { - @override - Widget build(BuildContext context) { - final contact = widget.contact; - return Scaffold( - backgroundColor: Colors.black, - appBar: AppBar( - title: const Text('Appel en cours'), - backgroundColor: Colors.black, - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const CircleAvatar( - radius: 100.0, - backgroundImage: - NetworkImage('https://thispersondoesnotexist.com/'), - backgroundColor: Colors.transparent, - ), - const SizedBox(height: 10.0), - // Add the contact name here - Text(contact.name, style: const TextStyle(fontSize: 40.0, color: Colors.white)), - // const SizedBox(height: 10.0), - const Text('99 : 59 : 59', style: - TextStyle(fontSize: 40.0, color: - Colors.white)), - const SizedBox(height: 50.0), - contact.isLocked - ? const Text('Con. Health - 98% (excellent)', - style: - TextStyle(fontSize: - 16.0,color: - Colors.green)) - : - const Text('No Icing available', - style: - TextStyle(fontSize: - 16.0,color: - Colors.white)), - const SizedBox(height: - 50.0), // Adjust size box height as needed - const Row( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - children:[ - Icon(Icons.mic_off,size: - 30.0,color: - Colors.white), - Icon(Icons.dialpad,size: - 30.0,color: - Colors.white), - Icon(Icons.more_vert,size: - 30.0,color: - Colors.white), - Icon(Icons.volume_up,size: - 30.0,color: - Colors.white), - ], - ), - const SizedBox(height: - 50.0), // Adjust size box height as needed - const Row( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - children:[ - Icon(Icons.pause,size: - 60.0,color: - Colors.white), - Icon(Icons.call_end,size: - 60.0,color: - Colors.red), - ], - ), - ], - ), - ), - ); - } -} - - -class DisplayAvatar extends StatelessWidget { - final Contact contact; - - const DisplayAvatar({super.key, required this.contact}); - - @override - Widget build(BuildContext context) { - return Stack( - children: [ - CircleAvatar( - child: Text(contact.name[0]), - ), - if (contact.isLocked) - const Positioned( - right: 0, - bottom: 0, - child: Icon( - Icons.lock, - color: Colors.white, - size: 20.0, - ), - ), - ], - ); - } -} - -// Create contact lists -class Contact { - final String name; - final String phoneNumber; - final bool isFavorite; - final bool isLocked; - - Contact(this.name, this.phoneNumber, {this.isFavorite = false, this.isLocked = false}); -} - -class History { - final Contact contact; - final DateTime date; - - History(this.contact, this.date); -} - -List contacts = [ - Contact('Axel NAVARRO BOUZEHRIR (arabe)', '0618859419'), - Contact('Fabrice Iguet', '0618958419'), - Contact('La Banque Axial', '0619358514'), - Contact('Maman', '0618955417', isFavorite: true, isLocked: true), - Contact('Micheline Verdet', '0618527419', isLocked: true), - Contact('Philippe Mogue', '0618955889', isFavorite: true), - Contact('Pizza Enrico Pucci', '0618951439', isLocked: true), - Contact('Quentin Aumas', '0610252019'), - Contact('Yohan HATOT', '0618102552', isFavorite: true, isLocked: true), - Contact('Zizou', '0618514479'), -]; - -List histories = [ - History(contacts[0], DateTime.now().subtract(const Duration(hours: 2))), - History(contacts[1], DateTime.now().subtract(const Duration(hours: 8))), - History(contacts[2], DateTime.now().subtract(const Duration(days: 3, hours: 4))), - History(contacts[3], DateTime.now().subtract(const Duration(days: 4, hours: 5))), - History(contacts[4], DateTime.now().subtract(const Duration(days: 5, hours: 6))), - History(contacts[5], DateTime.now().subtract(const Duration(days: 6, hours: 7))), - History(contacts[6], DateTime.now().subtract(const Duration(days: 7, hours: 8))), - History(contacts[7], DateTime.now().subtract(const Duration(days: 8, hours: 9))), - History(contacts[8], DateTime.now().subtract(const Duration(days: 9, hours: 10))), - History(contacts[9], DateTime.now().subtract(const Duration(days: 10, hours: 11))), -]; diff --git a/lib/pages/callingPage.dart b/lib/pages/callingPage.dart new file mode 100644 index 0000000..4a9789c --- /dev/null +++ b/lib/pages/callingPage.dart @@ -0,0 +1,93 @@ +import 'package:dialer/classes/contactClass.dart'; +import 'package:flutter/material.dart'; + +// display the calling page as if the call is already in progress +class _CallingPageState extends State { + @override + Widget build(BuildContext context) { + final contact = widget.contact; + return Scaffold( + backgroundColor: Colors.black, + appBar: AppBar( + title: const Text('Appel en cours'), + backgroundColor: Colors.black, + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const CircleAvatar( + radius: 100.0, + backgroundImage: + NetworkImage('https://thispersondoesnotexist.com/'), + backgroundColor: Colors.transparent, + ), + const SizedBox(height: 10.0), + // Add the contact name here + Text(contact.name, style: const TextStyle(fontSize: 40.0, color: Colors.white)), + // const SizedBox(height: 10.0), + const Text('99 : 59 : 59', style: + TextStyle(fontSize: 40.0, color: + Colors.white)), + const SizedBox(height: 50.0), + contact.isLocked + ? const Text('Con. Health - 98% (excellent)', + style: + TextStyle(fontSize: + 16.0,color: + Colors.green)) + : + const Text('No Icing available', + style: + TextStyle(fontSize: + 16.0,color: + Colors.white)), + const SizedBox(height: + 50.0), // Adjust size box height as needed + const Row( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children:[ + Icon(Icons.mic_off,size: + 30.0,color: + Colors.white), + Icon(Icons.dialpad,size: + 30.0,color: + Colors.white), + Icon(Icons.more_vert,size: + 30.0,color: + Colors.white), + Icon(Icons.volume_up,size: + 30.0,color: + Colors.white), + ], + ), + const SizedBox(height: + 50.0), // Adjust size box height as needed + const Row( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children:[ + Icon(Icons.pause,size: + 60.0,color: + Colors.white), + Icon(Icons.call_end,size: + 60.0,color: + Colors.red), + ], + ), + ], + ), + ), + ); + } +} + +class CallingPage extends StatefulWidget { + final Contact contact; + + const CallingPage({super.key, required this.contact}); + + @override + _CallingPageState createState() => _CallingPageState(); +} diff --git a/lib/pages/contact.dart b/lib/pages/contact.dart new file mode 100644 index 0000000..913cc42 --- /dev/null +++ b/lib/pages/contact.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; +import 'package:dialer/classes/contactClass.dart'; +import 'package:dialer/classes/displayContact.dart'; + +class ContactPage extends StatefulWidget { + const ContactPage({super.key}); + + @override + _ContactPageState createState() => _ContactPageState(); +} + +class _ContactPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + appBar: AppBar( + title: const Text('Contacts'), + ), + body: ListView.builder( + itemCount: contacts.length, + itemBuilder: (context, index) { + return DisplayContact(contact: contacts[index]); + }, + ), + ); + } +} + +List contacts = [ + Contact('Axel NAVARRO BOUZEHRIR (arabe)', '0618859419'), + Contact('Fabrice Iguet', '0618958419'), + Contact('La Banque Axial', '0619358514'), + Contact('Maman', '0618955417', isFavorite: true, isLocked: true), + Contact('Micheline Verdet', '0618527419', isLocked: true), + Contact('Philippe Mogue', '0618955889', isFavorite: true), + Contact('Pizza Enrico Pucci', '0618951439', isLocked: true), + Contact('Quentin Aumas', '0610252019'), + Contact('Yohan HATOT', '0618102552', isFavorite: true, isLocked: true), + Contact('Zizou', '0618514479'), +]; + diff --git a/lib/pages/favorites.dart b/lib/pages/favorites.dart new file mode 100644 index 0000000..7a40f70 --- /dev/null +++ b/lib/pages/favorites.dart @@ -0,0 +1,32 @@ +import 'package:dialer/classes/displayContact.dart'; +import 'package:dialer/pages/contact.dart'; +import 'package:flutter/material.dart'; + +class FavoritePage extends StatefulWidget { + const FavoritePage({super.key}); + + @override + _FavoritePageState createState() => _FavoritePageState(); +} + +class _FavoritePageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + appBar: AppBar( + title: const Text('Favorites'), + ), + body: ListView.builder( + itemCount: contacts.length, + itemBuilder: (context, index) { + if (contacts[index].isFavorite) { + return DisplayContact(contact: contacts[index]); + } else { + return const SizedBox.shrink(); + } + }, + ), + ); + } +} diff --git a/lib/pages/history.dart b/lib/pages/history.dart new file mode 100644 index 0000000..8a66265 --- /dev/null +++ b/lib/pages/history.dart @@ -0,0 +1,50 @@ +import 'package:dialer/classes/contactClass.dart'; +import 'package:dialer/pages/contact.dart'; +import 'package:flutter/material.dart'; +import 'package:dialer/classes/displayContact.dart'; + + +List histories = [ + History(contacts[0], DateTime.now().subtract(const Duration(hours: 2))), + History(contacts[1], DateTime.now().subtract(const Duration(hours: 8))), + History(contacts[2], DateTime.now().subtract(const Duration(days: 3, hours: 4))), + History(contacts[3], DateTime.now().subtract(const Duration(days: 4, hours: 5))), + History(contacts[4], DateTime.now().subtract(const Duration(days: 5, hours: 6))), + History(contacts[5], DateTime.now().subtract(const Duration(days: 6, hours: 7))), + History(contacts[6], DateTime.now().subtract(const Duration(days: 7, hours: 8))), + History(contacts[7], DateTime.now().subtract(const Duration(days: 8, hours: 9))), + History(contacts[8], DateTime.now().subtract(const Duration(days: 9, hours: 10))), + History(contacts[9], DateTime.now().subtract(const Duration(days: 10, hours: 11))), +]; + +class HistoryPage extends StatefulWidget { + const HistoryPage({super.key}); + + @override + _HistoryPageState createState() => _HistoryPageState(); +} + +class _HistoryPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + appBar: AppBar( + title: const Text('History'), + ), + body: ListView.builder( + itemCount: histories.length, + itemBuilder: (context, index) { + return DisplayContact(contact: histories[index].contact, history: histories[index]); + }, + ), + ); + } +} + +class History { + final Contact contact; + final DateTime date; + + History(this.contact, this.date); +} diff --git a/lib/pages/myHomePage.dart b/lib/pages/myHomePage.dart new file mode 100644 index 0000000..e428068 --- /dev/null +++ b/lib/pages/myHomePage.dart @@ -0,0 +1,65 @@ +import 'package:dialer/pages/contact.dart'; +import 'package:dialer/pages/favorites.dart'; +import 'package:dialer/pages/history.dart'; +import 'package:flutter/material.dart'; + +class _MyHomePageState extends State with SingleTickerProviderStateMixin { + late TabController _tabController; + + @override + void initState() { + super.initState(); + _tabController = TabController(length: 2, vsync: this, initialIndex: 1); + _tabController.addListener(_handleTabIndex); + } + + @override + void dispose() { + _tabController.removeListener(_handleTabIndex); + _tabController.dispose(); + super.dispose(); + } + + void _handleTabIndex() { + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: TabBarView( + controller: _tabController, + children: const [ + FavoritePage(), // Page des favoris + HistoryPage(), // Page de l'historique + ContactPage(), // Page des contacts + ], + ), + bottomNavigationBar: Container( + color: Colors.black, + child: TabBar( + controller: _tabController, + tabs: [ + Tab(icon: Icon(_tabController.index == 0 ? Icons.star : Icons.star_border)), + Tab(icon: Icon(_tabController.index == 1 ? Icons.access_time_filled : Icons.access_time_outlined)), + Tab(icon: Icon(_tabController.index == 2 ? Icons.contacts : Icons.contacts_outlined)), + ], + labelColor: Colors.white, + unselectedLabelColor: Colors.grey, + indicatorSize: TabBarIndicatorSize.label, + indicatorPadding: const EdgeInsets.only(bottom: -0), // Ajustez le padding pour élever la ligne blanche au-dessus des icônes si nécessaire + indicatorColor: Colors.white, // Couleur de la barre horizontale blanche + ), + ), + ); + } +} + + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key}); + + @override + _MyHomePageState createState() => _MyHomePageState(); +}