Advertisement
hisyam99

servicePage

Oct 5th, 2024
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 17.32 KB | Source Code | 0 0
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:flutter_rating_bar/flutter_rating_bar.dart';
  4. import '../controllers/servicePage_controller.dart';
  5.  
  6. class ServicePageView extends GetView<ServicePageController> {
  7.   const ServicePageView({super.key});
  8.  
  9.   @override
  10.   Widget build(BuildContext context) {
  11.     return GestureDetector(
  12.       onTap: () => FocusScope.of(context).unfocus(),
  13.       child: Scaffold(
  14.         backgroundColor: Theme.of(context).scaffoldBackgroundColor,
  15.         body: Stack(
  16.           children: [
  17.             CustomScrollView(
  18.               slivers: [
  19.                 SliverAppBar(
  20.                   expandedHeight: 300.0,
  21.                   pinned: true,
  22.                   flexibleSpace: FlexibleSpaceBar(
  23.                     background: _buildHeaderImage(),
  24.                   ),
  25.                   leading: IconButton(
  26.                     icon: const Icon(Icons.arrow_back),
  27.                     color: Colors.white,
  28.                     onPressed: () => Get.back(),
  29.                   ),
  30.                   actions: [
  31.                     IconButton(
  32.                       icon: const Icon(Icons.share_outlined),
  33.                       color: Colors.white,
  34.                       onPressed: controller.onSharePressed,
  35.                     ),
  36.                     IconButton(
  37.                       icon: const Icon(Icons.bookmark_border_rounded),
  38.                       color: Colors.white,
  39.                       onPressed: controller.onBookmarkPressed,
  40.                     ),
  41.                   ],
  42.                 ),
  43.                 SliverToBoxAdapter(
  44.                   child: _buildServiceDetails(context),
  45.                 ),
  46.                 SliverToBoxAdapter(
  47.                   child: _buildTabBarSection(context),
  48.                 ),
  49.                 const SliverToBoxAdapter(
  50.                   child: SizedBox(height: 100),
  51.                 ),
  52.               ],
  53.             ),
  54.             Positioned(
  55.               left: 0,
  56.               right: 0,
  57.               bottom: 0,
  58.               child: _buildBottomBar(context),
  59.             ),
  60.           ],
  61.         ),
  62.       ),
  63.     );
  64.   }
  65.  
  66.   Widget _buildHeaderImage() {
  67.     return Image.network(
  68.       'https://picsum.photos/seed/830/600',
  69.       width: double.infinity,
  70.       height: 300.0,
  71.       fit: BoxFit.cover,
  72.     );
  73.   }
  74.  
  75.   Widget _buildServiceDetails(BuildContext context) {
  76.     return Column(
  77.       mainAxisSize: MainAxisSize.max,
  78.       children: [
  79.         Padding(
  80.           padding: const EdgeInsets.all(16.0),
  81.           child: Column(
  82.             crossAxisAlignment: CrossAxisAlignment.start,
  83.             children: [
  84.               Row(
  85.                 mainAxisAlignment: MainAxisAlignment.spaceBetween,
  86.                 children: [
  87.                   const Text(
  88.                     'Device Service',
  89.                     style: TextStyle(
  90.                       fontFamily: 'Inter',
  91.                     ),
  92.                   ),
  93.                   Row(
  94.                     children: [
  95.                       Obx(() => RatingBar.builder(
  96.                             onRatingUpdate: controller.onRatingChanged,
  97.                             itemBuilder: (context, index) => const Icon(
  98.                               Icons.star_rounded,
  99.                               color: Colors.amber,
  100.                             ),
  101.                             initialRating: controller.rating.value,
  102.                             minRating: 1,
  103.                             direction: Axis.horizontal,
  104.                             itemCount: 5,
  105.                             itemSize: 24.0,
  106.                             allowHalfRating: true,
  107.                           )),
  108.                       Obx(() => Text(
  109.                             '${controller.rating.value}',
  110.                             style: const TextStyle(
  111.                               fontFamily: 'Inter',
  112.                             ),
  113.                           )),
  114.                     ],
  115.                   ),
  116.                 ],
  117.               ),
  118.               const SizedBox(height: 16),
  119.               const Column(
  120.                 crossAxisAlignment: CrossAxisAlignment.start,
  121.                 children: [
  122.                   Text(
  123.                     'Laptop Repair',
  124.                     style: TextStyle(
  125.                       fontFamily: 'Inter',
  126.                       fontSize: 28.0,
  127.                       fontWeight: FontWeight.bold,
  128.                     ),
  129.                   ),
  130.                   SizedBox(height: 8),
  131.                   Text(
  132.                     'Jl. Dharmahusada Indah Timur, Surabaya, Indonesia',
  133.                     style: TextStyle(
  134.                       fontFamily: 'Inter',
  135.                       fontSize: 12.0,
  136.                     ),
  137.                   ),
  138.                 ],
  139.               ),
  140.             ],
  141.           ),
  142.         ),
  143.       ],
  144.     );
  145.   }
  146.  
  147.   Widget _buildTabBarSection(BuildContext context) {
  148.     return DefaultTabController(
  149.       length: 3,
  150.       child: Column(
  151.         mainAxisSize: MainAxisSize.min,
  152.         children: [
  153.           TabBar(
  154.             controller: controller.tabController,
  155.             labelColor: const Color(0xFF0083B3),
  156.             unselectedLabelColor: Colors.grey,
  157.             tabs: const [
  158.               Tab(text: 'About'),
  159.               Tab(text: 'Gallery'),
  160.               Tab(text: 'Review'),
  161.             ],
  162.           ),
  163.           SizedBox(
  164.             height: 400.0, // Increased height to accommodate content
  165.             child: TabBarView(
  166.               controller: controller.tabController,
  167.               children: [
  168.                 _buildAboutTab(),
  169.                 _buildGalleryTab(),
  170.                 _buildReviewTab(),
  171.               ],
  172.             ),
  173.           ),
  174.         ],
  175.       ),
  176.     );
  177.   }
  178.  
  179.   Widget _buildAboutTab() {
  180.     return SingleChildScrollView(
  181.       padding: const EdgeInsets.all(24.0),
  182.       child: Column(
  183.         crossAxisAlignment: CrossAxisAlignment.start,
  184.         children: [
  185.           const Text(
  186.             'About Service',
  187.             style: TextStyle(
  188.               fontFamily: 'Inter',
  189.               fontWeight: FontWeight.bold,
  190.               fontSize: 16,
  191.             ),
  192.           ),
  193.           const SizedBox(height: 8),
  194.           const Text(
  195.             'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud Read more',
  196.             textAlign: TextAlign.justify,
  197.             style: TextStyle(
  198.               fontFamily: 'Inter',
  199.               fontSize: 14,
  200.             ),
  201.           ),
  202.           const SizedBox(height: 24),
  203.           _buildServiceProvider(),
  204.         ],
  205.       ),
  206.     );
  207.   }
  208.  
  209.   Widget _buildServiceProvider() {
  210.     return Column(
  211.       crossAxisAlignment: CrossAxisAlignment.start,
  212.       children: [
  213.         const Text(
  214.           'Service Provider',
  215.           style: TextStyle(
  216.             fontFamily: 'Inter',
  217.             fontWeight: FontWeight.bold,
  218.             fontSize: 16,
  219.           ),
  220.         ),
  221.         const SizedBox(height: 8),
  222.         Row(
  223.           children: [
  224.             ClipRRect(
  225.               borderRadius: BorderRadius.circular(24.0),
  226.               child: Image.network(
  227.                 'https://picsum.photos/seed/751/600',
  228.                 width: 50.0,
  229.                 height: 50.0,
  230.                 fit: BoxFit.cover,
  231.               ),
  232.             ),
  233.             const Expanded(
  234.               child: Padding(
  235.                 padding: EdgeInsets.all(8.0),
  236.                 child: Column(
  237.                   crossAxisAlignment: CrossAxisAlignment.start,
  238.                   children: [
  239.                     Text(
  240.                       'Bob',
  241.                       style: TextStyle(
  242.                         fontFamily: 'Inter',
  243.                         fontWeight: FontWeight.bold,
  244.                       ),
  245.                     ),
  246.                     Text(
  247.                       'Service Provider',
  248.                       style: TextStyle(
  249.                         fontFamily: 'Inter',
  250.                         fontSize: 12,
  251.                       ),
  252.                     ),
  253.                   ],
  254.                 ),
  255.               ),
  256.             ),
  257.             Row(
  258.               children: [
  259.                 IconButton(
  260.                   icon: const Icon(Icons.chat_bubble_rounded),
  261.                   color: const Color(0xFF0083B3),
  262.                   onPressed: () {
  263.                     Get.toNamed('/chat');
  264.                   },
  265.                 ),
  266.                 IconButton(
  267.                   icon: const Icon(Icons.call_rounded),
  268.                   color: const Color(0xFF0083B3),
  269.                   onPressed: () {
  270.                     Get.toNamed('/call');
  271.                   },
  272.                 ),
  273.               ],
  274.             ),
  275.           ],
  276.         ),
  277.       ],
  278.     );
  279.   }
  280.  
  281.   Widget _buildGalleryTab() {
  282.     return Padding(
  283.       padding: const EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0),
  284.       child: Column(
  285.         crossAxisAlignment: CrossAxisAlignment.start,
  286.         children: [
  287.           Row(
  288.             mainAxisAlignment: MainAxisAlignment.spaceBetween,
  289.             children: [
  290.               const Text(
  291.                 'Gallery (25)',
  292.                 style: TextStyle(
  293.                   fontFamily: 'Inter Tight',
  294.                   fontSize: 16,
  295.                   fontWeight: FontWeight.bold,
  296.                 ),
  297.               ),
  298.               TextButton(
  299.                 onPressed: () {
  300.                   Get.toNamed('/gallery');
  301.                 },
  302.                 child: const Text(
  303.                   'View All',
  304.                   style: TextStyle(
  305.                     color: Color(0xFF0083B3),
  306.                   ),
  307.                 ),
  308.               ),
  309.             ],
  310.           ),
  311.           const SizedBox(height: 16),
  312.           Expanded(
  313.             child: GridView.builder(
  314.               gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
  315.                 crossAxisCount: 2,
  316.                 crossAxisSpacing: 10.0,
  317.                 mainAxisSpacing: 10.0,
  318.               ),
  319.               itemCount: 4,
  320.               itemBuilder: (context, index) {
  321.                 return ClipRRect(
  322.                   borderRadius: BorderRadius.circular(8.0),
  323.                   child: Image.network(
  324.                     'https://picsum.photos/seed/${400 + index}/600',
  325.                     fit: BoxFit.cover,
  326.                   ),
  327.                 );
  328.               },
  329.             ),
  330.           ),
  331.         ],
  332.       ),
  333.     );
  334.   }
  335.  
  336.   Widget _buildReviewTab() {
  337.     return SingleChildScrollView(
  338.       child: Padding(
  339.         padding: const EdgeInsets.all(16.0),
  340.         child: Column(
  341.           crossAxisAlignment: CrossAxisAlignment.start,
  342.           children: [
  343.             TextField(
  344.               decoration: InputDecoration(
  345.                 prefixIcon: const Icon(Icons.search),
  346.                 hintText: 'Search in reviews',
  347.                 border: OutlineInputBorder(
  348.                   borderRadius: BorderRadius.circular(12),
  349.                 ),
  350.               ),
  351.             ),
  352.             const SizedBox(height: 16),
  353.             SingleChildScrollView(
  354.               scrollDirection: Axis.horizontal,
  355.               child: Row(
  356.                 children: [
  357.                   ElevatedButton.icon(
  358.                     onPressed: () {},
  359.                     icon: const Icon(Icons.verified),
  360.                     label: const Text('Verified'),
  361.                     style: ElevatedButton.styleFrom(
  362.                       shape: const StadiumBorder(),
  363.                     ),
  364.                   ),
  365.                   const SizedBox(width: 8),
  366.                   ElevatedButton.icon(
  367.                     onPressed: () {},
  368.                     icon: const Icon(Icons.update),
  369.                     label: const Text('Latest'),
  370.                     style: ElevatedButton.styleFrom(
  371.                       shape: const StadiumBorder(),
  372.                     ),
  373.                   ),
  374.                   const SizedBox(width: 8),
  375.                   ElevatedButton.icon(
  376.                     onPressed: () {},
  377.                     icon: const Icon(Icons.photo),
  378.                     label: const Text('With Photos'),
  379.                     style: ElevatedButton.styleFrom(
  380.                       shape: const StadiumBorder(),
  381.                     ),
  382.                   ),
  383.                   const SizedBox(width: 8),
  384.                   ElevatedButton.icon(
  385.                     onPressed: () {},
  386.                     icon: const Icon(Icons.star),
  387.                     label: const Text('Rating Only'),
  388.                     style: ElevatedButton.styleFrom(
  389.                       shape: const StadiumBorder(),
  390.                     ),
  391.                   ),
  392.                 ],
  393.               ),
  394.             ),
  395.             const SizedBox(height: 16),
  396.             Card(
  397.               shape: RoundedRectangleBorder(
  398.                 borderRadius: BorderRadius.circular(12),
  399.               ),
  400.               elevation: 2,
  401.               child: const Padding(
  402.                 padding: EdgeInsets.all(16.0),
  403.                 child: Column(
  404.                   crossAxisAlignment: CrossAxisAlignment.start,
  405.                   children: [
  406.                     Row(
  407.                       children: [
  408.                         CircleAvatar(
  409.                           backgroundImage: NetworkImage(
  410.                               'https://picsum.photos/seed/751/600'),
  411.                           radius: 20,
  412.                         ),
  413.                         SizedBox(width: 8),
  414.                         Column(
  415.                           crossAxisAlignment: CrossAxisAlignment.start,
  416.                           children: [
  417.                             Text(
  418.                               'Rick Astley',
  419.                               style: TextStyle(fontWeight: FontWeight.bold),
  420.                             ),
  421.                             Text(
  422.                               '2 months ago',
  423.                               style: TextStyle(color: Colors.grey),
  424.                             ),
  425.                           ],
  426.                         ),
  427.                         Spacer(),
  428.                         Row(
  429.                           children: [
  430.                             Icon(Icons.star, color: Colors.amber, size: 20),
  431.                             Text('4.9',
  432.                                 style: TextStyle(fontWeight: FontWeight.bold)),
  433.                           ],
  434.                         ),
  435.                       ],
  436.                     ),
  437.                     SizedBox(height: 8),
  438.                     Text(
  439.                       'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
  440.                       style: TextStyle(fontSize: 14),
  441.                     ),
  442.                   ],
  443.                 ),
  444.               ),
  445.             ),
  446.           ],
  447.         ),
  448.       ),
  449.     );
  450.   }
  451.  
  452.   Widget _buildBottomBar(BuildContext context) {
  453.     return Expanded(
  454.       child: Align(
  455.         alignment: const Alignment(0.0, 1.0),
  456.         child: Container(
  457.           width: double.infinity,
  458.           height: 100.0,
  459.           decoration: BoxDecoration(
  460.             color: Theme.of(context).cardColor,
  461.             boxShadow: const [
  462.               BoxShadow(
  463.                 blurRadius: 4.0,
  464.                 color: Colors.black26,
  465.                 offset: Offset(0.0, -2.0),
  466.               )
  467.             ],
  468.             borderRadius: const BorderRadius.only(
  469.               topLeft: Radius.circular(10.0),
  470.               topRight: Radius.circular(10.0),
  471.             ),
  472.           ),
  473.           child: Padding(
  474.             padding: const EdgeInsets.symmetric(horizontal: 24.0),
  475.             child: Row(
  476.               mainAxisAlignment: MainAxisAlignment.spaceBetween,
  477.               children: [
  478.                 Column(
  479.                   mainAxisAlignment: MainAxisAlignment.center,
  480.                   crossAxisAlignment: CrossAxisAlignment.start,
  481.                   children: [
  482.                     const Text(
  483.                       'Total Price',
  484.                       style: TextStyle(
  485.                         fontFamily: 'Inter',
  486.                       ),
  487.                     ),
  488.                     Text(
  489.                       '\$15.00',
  490.                       style: TextStyle(
  491.                         fontFamily: 'Inter',
  492.                         color: Theme.of(context).primaryColor,
  493.                         fontWeight: FontWeight.bold,
  494.                       ),
  495.                     ),
  496.                   ],
  497.                 ),
  498.                 ElevatedButton(
  499.                   onPressed: controller.onBookNowPressed,
  500.                   style: ElevatedButton.styleFrom(
  501.                     backgroundColor: const Color(0xFF0083B3),
  502.                     shape: RoundedRectangleBorder(
  503.                       borderRadius: BorderRadius.circular(20.0),
  504.                     ),
  505.                     padding: const EdgeInsets.symmetric(
  506.                       horizontal: 32.0,
  507.                       vertical: 16.0,
  508.                     ),
  509.                   ),
  510.                   child: const Text(
  511.                     'Book Now',
  512.                     style: TextStyle(
  513.                       color: Colors.white,
  514.                       fontFamily: 'Inter Tight',
  515.                     ),
  516.                   ),
  517.                 ),
  518.               ],
  519.             ),
  520.           ),
  521.         ),
  522.       ),
  523.     );
  524.   }
  525. }
  526.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement