diff --git a/lib/main.dart b/lib/main.dart index e16e375..bc6e7d7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -21,29 +21,133 @@ class MyApp extends StatelessWidget { } } -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key}); + +// REUSABLE HEADER WIDGET — USED IN BOTH HOME PAGE & SHOP PAGE +class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { + final String title; + + const CustomAppBar({ + super.key, + required this.title, + }); @override - State createState() => _MyHomePageState(); + Size get preferredSize => const Size.fromHeight(60); + + @override + Widget build(BuildContext context) { + return AppBar( + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + leading: Builder( + builder: (context) { + return IconButton( + icon: const Icon(Icons.menu), + onPressed: () { + Scaffold.of(context).openDrawer(); + }, + tooltip: 'Menu', + ); + }, + ), + title: Row( + children: [ + SizedBox( + width: 40, + child: SvgPicture.network( + 'https://nest-frontend-v6.vercel.app/assets/imgs/theme/logo.svg', + placeholderBuilder: (context) => const CircularProgressIndicator(), + ), + ), + const SizedBox(width: 8), + Text( + 'Nest', + style: const TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Colors.green, + ), + ), + const SizedBox(width: 4), + const Text( + 'MART & GROCERY', + style: TextStyle( + fontSize: 10, + color: Colors.grey, + ), + ), + ], + ), + actions: [ + Stack( + children: [ + IconButton( + icon: const Icon(Icons.favorite_border), + onPressed: () {}, + ), + Positioned( + top: 4, + right: 4, + child: Container( + padding: const EdgeInsets.all(1), + decoration: const BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + constraints: const BoxConstraints(minWidth: 16, minHeight: 16), + child: const Center( + child: Text( + '4', + style: TextStyle(color: Colors.white, fontSize: 10), + ), + ), + ), + ), + ], + ), + Stack( + children: [ + IconButton( + icon: const Icon(Icons.shopping_cart_outlined), + onPressed: () {}, + ), + Positioned( + top: 4, + right: 4, + child: Container( + padding: const EdgeInsets.all(1), + decoration: const BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + constraints: const BoxConstraints(minWidth: 16, minHeight: 16), + child: const Center( + child: Text( + '2', + style: TextStyle(color: Colors.white, fontSize: 10), + ), + ), + ), + ), + ], + ), + ], + ); + } +} +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// REUSABLE DRAWER WIDGET +class AppDrawer extends StatefulWidget { + const AppDrawer({super.key}); + + @override + State createState() => _AppDrawerState(); } -class _MyHomePageState extends State { - int _counter = 0; - - void _decrementCounter() { - setState(() { - _counter--; - }); - } - - static const String logoUrl = - 'https://nest-frontend-v6.vercel.app/assets/imgs/theme/logo.svg'; - - // Track expanded top-level items for styling (e.g., "Shop") +class _AppDrawerState extends State { Set _expandedTopItems = {'Shop'}; - // Reusable widget for sub-menu items with hover/tap effect Widget _buildSubItem(String title, {VoidCallback? onTap}) { return MouseRegion( cursor: SystemMouseCursors.click, @@ -61,7 +165,6 @@ class _MyHomePageState extends State { ); } - // Reusable styled title for ExpansionTile (NO arrow inside!) Widget _buildTopItem(String title) { final bool isActive = _expandedTopItems.contains(title); return MouseRegion( @@ -83,450 +186,419 @@ class _MyHomePageState extends State { ); } + static const String logoUrl = + 'https://nest-frontend-v6.vercel.app/assets/imgs/theme/logo.svg'; + @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: Theme.of(context).colorScheme.inversePrimary, - leading: Builder( - builder: (context) { - return IconButton( - icon: const Icon(Icons.menu), - onPressed: () { - Scaffold.of(context).openDrawer(); - }, - tooltip: 'Menu', - ); - }, - ), - title: const Text( - 'Nest', - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Colors.green, - ), - ), - actions: [ - Stack( - children: [ - IconButton( - icon: const Icon(Icons.favorite_border), - onPressed: () {}, - ), - Positioned( - top: 4, - right: 4, - child: Container( - padding: const EdgeInsets.all(1), - decoration: const BoxDecoration( - color: Colors.red, - shape: BoxShape.circle, - ), - constraints: const BoxConstraints(minWidth: 16, minHeight: 16), - child: const Center( - child: Text( - '4', - style: TextStyle(color: Colors.white, fontSize: 10), - ), + return Drawer( + child: ListView( + padding: EdgeInsets.zero, + children: [ + DrawerHeader( + decoration: BoxDecoration( + color: Colors.green[50], + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SvgPicture.network( + logoUrl, + height: 40, + placeholderBuilder: (context) => const SizedBox( + width: 160, + height: 40, + child: Center(child: Text('Nest')), ), ), + IconButton( + icon: const Icon(Icons.close), + onPressed: () { + Navigator.pop(context); + }, + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.all(16.0), + child: TextField( + decoration: InputDecoration( + hintText: 'Search for items...', + prefixIcon: const Icon(Icons.search), + border: OutlineInputBorder(), + ), + ), + ), + + // Home + ExpansionTile( + title: _buildTopItem('Home'), + onExpansionChanged: (expanded) { + setState(() { + if (expanded) { + _expandedTopItems.add('Home'); + } else { + _expandedTopItems.remove('Home'); + } + }); + }, + children: [ + _buildSubItem('Home 1'), + _buildSubItem('Home 2'), + _buildSubItem('Home 3'), + _buildSubItem('Home 4'), + _buildSubItem('Home 5'), + _buildSubItem('Home 6'), + ], + ), + + // Shop (pre-expanded) + ExpansionTile( + initiallyExpanded: true, + title: _buildTopItem('Shop'), + onExpansionChanged: (expanded) { + setState(() { + if (expanded) { + _expandedTopItems.add('Shop'); + } else { + _expandedTopItems.remove('Shop'); + } + }); + }, + children: [ + _buildSubItem( + 'Shop Grid - Right Sidebar', + onTap: () { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const ShopGridRightSidebarPage(), + ), + ); + }, + ), + _buildSubItem('Shop Grid - Left Sidebar'), + _buildSubItem('Shop List - Right Sidebar'), + _buildSubItem('Shop - Wide'), + ExpansionTile( + title: const Text('Single Product'), + children: [ + _buildSubItem('Product - Right Sidebar'), + _buildSubItem('Product - Left Sidebar'), + _buildSubItem('Product - No Sidebar'), + _buildSubItem('Product - Vendor Infor'), + ], + ), + ExpansionTile( + title: const Text('Shop Invoice'), + children: [ + _buildSubItem('Shop Invoice 1'), + _buildSubItem('Shop Invoice 2'), + _buildSubItem('Shop Invoice 3'), + _buildSubItem('Shop Invoice 4'), + _buildSubItem('Shop Invoice 5'), + _buildSubItem('Shop Invoice 6'), + ], ), ], ), - Stack( + + // Vendors + ExpansionTile( + title: _buildTopItem('Vendors'), + onExpansionChanged: (expanded) { + setState(() { + if (expanded) { + _expandedTopItems.add('Vendors'); + } else { + _expandedTopItems.remove('Vendors'); + } + }); + }, children: [ - IconButton( - icon: const Icon(Icons.shopping_cart_outlined), - onPressed: () {}, + _buildSubItem('Vendors Grid'), + _buildSubItem('Vendore List'), + ], + ), + + // Mega Menu + ExpansionTile( + title: _buildTopItem('Mega Menu'), + onExpansionChanged: (expanded) { + setState(() { + if (expanded) { + _expandedTopItems.add('Mega Menu'); + } else { + _expandedTopItems.remove('Mega Menu'); + } + }); + }, + children: [ + _buildSubItem("Women's Fashion"), + _buildSubItem("Men's Fashion"), + _buildSubItem('Technology'), + ], + ), + + // Blog + ExpansionTile( + title: _buildTopItem('Blog'), + onExpansionChanged: (expanded) { + setState(() { + if (expanded) { + _expandedTopItems.add('Blog'); + } else { + _expandedTopItems.remove('Blog'); + } + }); + }, + children: [ + _buildSubItem('Blog Category Grid'), + _buildSubItem('Blog Category List'), + _buildSubItem('Blog Category Big'), + _buildSubItem('Blog Category Wide'), + ExpansionTile( + title: const Text('Single Product Layout'), + children: [ + _buildSubItem('Layout A'), + _buildSubItem('Layout B'), + ], ), - Positioned( - top: 4, - right: 4, - child: Container( - padding: const EdgeInsets.all(1), - decoration: const BoxDecoration( - color: Colors.red, - shape: BoxShape.circle, - ), - constraints: const BoxConstraints(minWidth: 16, minHeight: 16), - child: const Center( - child: Text( - '2', - style: TextStyle(color: Colors.white, fontSize: 10), + ], + ), + + // Pages + ExpansionTile( + title: _buildTopItem('Pages'), + onExpansionChanged: (expanded) { + setState(() { + if (expanded) { + _expandedTopItems.add('Pages'); + } else { + _expandedTopItems.remove('Pages'); + } + }); + }, + children: [ + _buildSubItem('About Us'), + _buildSubItem('Contact'), + _buildSubItem('My Account'), + _buildSubItem('Register'), + _buildSubItem('Forget Password'), + _buildSubItem('Reset Password'), + _buildSubItem('Purchase Guide'), + _buildSubItem('Privacy Policy'), + _buildSubItem('Terms of Service'), + _buildSubItem('404 Page'), + ], + ), + + // Language + ExpansionTile( + title: _buildTopItem('Language'), + onExpansionChanged: (expanded) { + setState(() { + if (expanded) { + _expandedTopItems.add('Language'); + } else { + _expandedTopItems.remove('Language'); + } + }); + }, + children: [ + _buildSubItem('English'), + _buildSubItem('French'), + _buildSubItem('German'), + _buildSubItem('Spanish'), + ], + ), + + const Divider(), + + // Footer inside drawer + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + MouseRegion( + cursor: SystemMouseCursors.click, + child: InkWell( + onTap: () => Navigator.pop(context), + borderRadius: BorderRadius.circular(8), + hoverColor: Colors.green[50], + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + const Icon(Icons.location_on, color: Colors.green), + const SizedBox(width: 8), + const Text('Our location'), + ], + ), ), ), ), - ), - ], + MouseRegion( + cursor: SystemMouseCursors.click, + child: InkWell( + onTap: () {}, + borderRadius: BorderRadius.circular(8), + hoverColor: Colors.green[50], + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + const Icon(Icons.person_outline, color: Colors.green), + const SizedBox(width: 8), + const Text('Log In / Sign Up'), + ], + ), + ), + ), + ), + MouseRegion( + cursor: SystemMouseCursors.click, + child: InkWell( + onTap: () {}, + borderRadius: BorderRadius.circular(8), + hoverColor: Colors.green[50], + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + const Icon(Icons.headset_mic, color: Colors.green), + const SizedBox(width: 8), + const Text('(+01) - 2345 - 6789'), + ], + ), + ), + ), + ), + const SizedBox(height: 16), + const Text( + 'Follow Us', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 12), + Row( + children: [ + CircleAvatar( + backgroundColor: Colors.green, + radius: 20, + child: IconButton( + icon: const Icon(Icons.facebook, color: Colors.white, size: 20), + onPressed: () {}, + ), + ), + const SizedBox(width: 8), + CircleAvatar( + backgroundColor: Colors.green, + radius: 20, + child: IconButton( + icon: const Icon(Icons.access_time, color: Colors.white, size: 20), + onPressed: () {}, + ), + ), + const SizedBox(width: 8), + CircleAvatar( + backgroundColor: Colors.green, + radius: 20, + child: IconButton( + icon: const Icon(Icons.camera_alt, color: Colors.white, size: 20), + onPressed: () {}, + ), + ), + const SizedBox(width: 8), + CircleAvatar( + backgroundColor: Colors.green, + radius: 20, + child: IconButton( + icon: const Icon(Icons.play_arrow, color: Colors.white, size: 20), + onPressed: () {}, + ), + ), + const SizedBox(width: 8), + CircleAvatar( + backgroundColor: Colors.green, + radius: 20, + child: IconButton( + icon: const Icon(Icons.play_circle_outline, color: Colors.white, size: 20), + onPressed: () {}, + ), + ), + ], + ), + const SizedBox(height: 20), + Text( + 'Copyright 2024 © Nest. All rights reserved. Powered by AliThemes.', + style: TextStyle( + fontSize: 12, + color: Colors.grey[600], + ), + ), + ], + ), ), ], ), - drawer: Drawer( - child: ListView( - padding: EdgeInsets.zero, - children: [ - DrawerHeader( - decoration: BoxDecoration( - color: Colors.green[50], - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SvgPicture.network( - logoUrl, - height: 40, - placeholderBuilder: (context) => const SizedBox( - width: 160, - height: 40, - child: Center(child: Text('Nest')), - ), - ), - IconButton( - icon: const Icon(Icons.close), - onPressed: () { - Navigator.pop(context); - }, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.all(16.0), - child: TextField( - decoration: InputDecoration( - hintText: 'Search for items...', - prefixIcon: const Icon(Icons.search), - border: OutlineInputBorder(), - ), - ), - ), + ); + } +} - // Home - ExpansionTile( - title: _buildTopItem('Home'), - onExpansionChanged: (expanded) { - setState(() { - if (expanded) { - _expandedTopItems.add('Home'); - } else { - _expandedTopItems.remove('Home'); - } - }); - }, - children: [ - _buildSubItem('Home 1'), - _buildSubItem('Home 2'), - _buildSubItem('Home 3'), - _buildSubItem('Home 4'), - _buildSubItem('Home 5'), - _buildSubItem('Home 6'), - ], - ), +// NEW PAGE: Shop Grid - Right Sidebar +class ShopGridRightSidebarPage extends StatelessWidget { + const ShopGridRightSidebarPage({super.key}); - // Shop (pre-expanded) - ExpansionTile( - initiallyExpanded: true, - title: _buildTopItem('Shop'), - onExpansionChanged: (expanded) { - setState(() { - if (expanded) { - _expandedTopItems.add('Shop'); - } else { - _expandedTopItems.remove('Shop'); - } - }); - }, - children: [ - _buildSubItem('Shop Grid - Right Sidebar'), - _buildSubItem('Shop Grid - Left Sidebar'), - _buildSubItem('Shop List - Right Sidebar'), - _buildSubItem('Shop - Wide'), - ExpansionTile( - title: const Text('Single Product'), - children: [ - _buildSubItem('Product - Right Sidebar'), - _buildSubItem('Product - Left Sidebar'), - _buildSubItem('Product - No Sidebar'), - _buildSubItem('Product - Vendor Infor'), - ], - ), - ExpansionTile( - title: const Text('Shop Invoice'), - children: [ - _buildSubItem('Shop Invoice 1'), - _buildSubItem('Shop Invoice 2'), - _buildSubItem('Shop Invoice 3'), - _buildSubItem('Shop Invoice 4'), - _buildSubItem('Shop Invoice 5'), - _buildSubItem('Shop Invoice 6'), - ], - ), - ], - ), - - // Vendors - ExpansionTile( - title: _buildTopItem('Vendors'), - onExpansionChanged: (expanded) { - setState(() { - if (expanded) { - _expandedTopItems.add('Vendors'); - } else { - _expandedTopItems.remove('Vendors'); - } - }); - }, - children: [ - _buildSubItem('Vendors Grid'), - _buildSubItem('Vendore List'), - ], - ), - - // Mega Menu - ExpansionTile( - title: _buildTopItem('Mega Menu'), - onExpansionChanged: (expanded) { - setState(() { - if (expanded) { - _expandedTopItems.add('Mega Menu'); - } else { - _expandedTopItems.remove('Mega Menu'); - } - }); - }, - children: [ - _buildSubItem("Women's Fashion"), - _buildSubItem("Men's Fashion"), - _buildSubItem('Technology'), - ], - ), - - // Blog - ExpansionTile( - title: _buildTopItem('Blog'), - onExpansionChanged: (expanded) { - setState(() { - if (expanded) { - _expandedTopItems.add('Blog'); - } else { - _expandedTopItems.remove('Blog'); - } - }); - }, - children: [ - _buildSubItem('Blog Category Grid'), - _buildSubItem('Blog Category List'), - _buildSubItem('Blog Category Big'), - _buildSubItem('Blog Category Wide'), - ExpansionTile( - title: const Text('Single Product Layout'), - children: [ - _buildSubItem('Layout A'), - _buildSubItem('Layout B'), - ], - ), - ], - ), - - // Pages - ExpansionTile( - title: _buildTopItem('Pages'), - onExpansionChanged: (expanded) { - setState(() { - if (expanded) { - _expandedTopItems.add('Pages'); - } else { - _expandedTopItems.remove('Pages'); - } - }); - }, - children: [ - _buildSubItem('About Us'), - _buildSubItem('Contact'), - _buildSubItem('My Account'), - _buildSubItem('Register'), - _buildSubItem('Forget Password'), - _buildSubItem('Reset Password'), - _buildSubItem('Purchase Guide'), - _buildSubItem('Privacy Policy'), - _buildSubItem('Terms of Service'), - _buildSubItem('404 Page'), - ], - ), - - // Language - ExpansionTile( - title: _buildTopItem('Language'), - onExpansionChanged: (expanded) { - setState(() { - if (expanded) { - _expandedTopItems.add('Language'); - } else { - _expandedTopItems.remove('Language'); - } - }); - }, - children: [ - _buildSubItem('English'), - _buildSubItem('French'), - _buildSubItem('German'), - _buildSubItem('Spanish'), - ], - ), - - const Divider(), - - // Footer inside drawer - Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - MouseRegion( - cursor: SystemMouseCursors.click, - child: InkWell( - onTap: () => Navigator.pop(context), - borderRadius: BorderRadius.circular(8), - hoverColor: Colors.green[50], - splashColor: Colors.transparent, - highlightColor: Colors.transparent, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Row( - children: [ - const Icon(Icons.location_on, color: Colors.green), - const SizedBox(width: 8), - const Text('Our location'), - ], - ), - ), - ), - ), - MouseRegion( - cursor: SystemMouseCursors.click, - child: InkWell( - onTap: () {}, - borderRadius: BorderRadius.circular(8), - hoverColor: Colors.green[50], - splashColor: Colors.transparent, - highlightColor: Colors.transparent, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Row( - children: [ - const Icon(Icons.person_outline, color: Colors.green), - const SizedBox(width: 8), - const Text('Log In / Sign Up'), - ], - ), - ), - ), - ), - MouseRegion( - cursor: SystemMouseCursors.click, - child: InkWell( - onTap: () {}, - borderRadius: BorderRadius.circular(8), - hoverColor: Colors.green[50], - splashColor: Colors.transparent, - highlightColor: Colors.transparent, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Row( - children: [ - const Icon(Icons.headset_mic, color: Colors.green), - const SizedBox(width: 8), - const Text('(+01) - 2345 - 6789'), - ], - ), - ), - ), - ), - const SizedBox(height: 16), - const Text( - 'Follow Us', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 12), - Row( - children: [ - CircleAvatar( - backgroundColor: Colors.green, - radius: 20, - child: IconButton( - icon: const Icon(Icons.facebook, color: Colors.white, size: 20), - onPressed: () {}, - ), - ), - const SizedBox(width: 8), - CircleAvatar( - backgroundColor: Colors.green, - radius: 20, - child: IconButton( - icon: const Icon(Icons.access_time, color: Colors.white, size: 20), - onPressed: () {}, - ), - ), - const SizedBox(width: 8), - CircleAvatar( - backgroundColor: Colors.green, - radius: 20, - child: IconButton( - icon: const Icon(Icons.camera_alt, color: Colors.white, size: 20), - onPressed: () {}, - ), - ), - const SizedBox(width: 8), - CircleAvatar( - backgroundColor: Colors.green, - radius: 20, - child: IconButton( - icon: const Icon(Icons.play_arrow, color: Colors.white, size: 20), - onPressed: () {}, - ), - ), - const SizedBox(width: 8), - CircleAvatar( - backgroundColor: Colors.green, - radius: 20, - child: IconButton( - icon: const Icon(Icons.play_circle_outline, color: Colors.white, size: 20), - onPressed: () {}, - ), - ), - ], - ), - const SizedBox(height: 20), - Text( - 'Copyright 2024 © Nest. All rights reserved. Powered by AliThemes.', - style: TextStyle( - fontSize: 12, - color: Colors.grey[600], - ), - ), - ], - ), - ), - ], + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: const CustomAppBar(title: 'Shop Grid - Right Sidebar'), + drawer: const AppDrawer(), // ✅ Drawer attached → hamburger works! + body: const Center( + child: Text( + 'Hello', + style: TextStyle(fontSize: 24), ), ), - body: Center( + ); + } +} +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// MAIN HOME PAGE +class MyHomePage extends StatelessWidget { + const MyHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: const CustomAppBar(title: 'Home'), + drawer: const AppDrawer(), // ✅ Same drawer + body: const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Text('Hello'), + Text('Hello'), Text( - '$_counter', - style: const TextStyle(fontSize: 48), + '0', + style: TextStyle(fontSize: 48), ), ], ), ), - ); } } \ No newline at end of file