diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml new file mode 100644 index 0000000..3383c71 --- /dev/null +++ b/.github/workflows/dart.yml @@ -0,0 +1,42 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Dart + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + # Note: This workflow uses the latest stable version of the Dart SDK. + # You can specify other versions if desired, see documentation here: + # https://github.com/dart-lang/setup-dart/blob/main/README.md + # - uses: dart-lang/setup-dart@v1 + - uses: dart-lang/setup-dart@9a04e6d73cca37bd455e0608d7e5092f881fd603 + + - name: Install dependencies + run: dart pub get + + # Uncomment this step to verify the use of 'dart format' on each commit. + # - name: Verify formatting + # run: dart format --output=none --set-exit-if-changed . + + # Consider passing '--fatal-infos' for slightly stricter analysis. + - name: Analyze project source + run: dart analyze + + # Your project will need to have tests in test/ and a dependency on + # package:test for this step to succeed. Note that Flutter projects will + # want to change this to 'flutter test'. + - name: Run tests + run: dart test diff --git a/pet_care/assets/images/8488254.jpg b/pet_care/assets/images/8488254.jpg new file mode 100644 index 0000000..b60d085 Binary files /dev/null and b/pet_care/assets/images/8488254.jpg differ diff --git a/pet_care/assets/images/cat1.png b/pet_care/assets/images/cat1.png new file mode 100644 index 0000000..d431221 Binary files /dev/null and b/pet_care/assets/images/cat1.png differ diff --git a/pet_care/assets/images/catproduct1.jpg b/pet_care/assets/images/catproduct1.jpg new file mode 100644 index 0000000..c630ec8 Binary files /dev/null and b/pet_care/assets/images/catproduct1.jpg differ diff --git a/pet_care/assets/images/dog.png b/pet_care/assets/images/dog.png new file mode 100644 index 0000000..26d0b46 Binary files /dev/null and b/pet_care/assets/images/dog.png differ diff --git a/pet_care/assets/images/dog1.png b/pet_care/assets/images/dog1.png new file mode 100644 index 0000000..d940038 Binary files /dev/null and b/pet_care/assets/images/dog1.png differ diff --git a/pet_care/assets/images/facebook.png b/pet_care/assets/images/facebook.png new file mode 100644 index 0000000..d8b4bdb Binary files /dev/null and b/pet_care/assets/images/facebook.png differ diff --git a/pet_care/assets/images/g.png b/pet_care/assets/images/g.png new file mode 100644 index 0000000..2963066 Binary files /dev/null and b/pet_care/assets/images/g.png differ diff --git a/pet_care/assets/images/paw.png b/pet_care/assets/images/paw.png new file mode 100644 index 0000000..7c4ff50 Binary files /dev/null and b/pet_care/assets/images/paw.png differ diff --git a/pet_care/assets/images/pic3.zip b/pet_care/assets/images/pic3.zip new file mode 100644 index 0000000..9aef62b Binary files /dev/null and b/pet_care/assets/images/pic3.zip differ diff --git a/pet_care/assets/images/product1.png b/pet_care/assets/images/product1.png new file mode 100644 index 0000000..20318fd Binary files /dev/null and b/pet_care/assets/images/product1.png differ diff --git a/pet_care/assets/images/product2.jpg b/pet_care/assets/images/product2.jpg new file mode 100644 index 0000000..c4102cc Binary files /dev/null and b/pet_care/assets/images/product2.jpg differ diff --git a/pet_care/assets/images/product3.jpg b/pet_care/assets/images/product3.jpg new file mode 100644 index 0000000..a7ac60c Binary files /dev/null and b/pet_care/assets/images/product3.jpg differ diff --git a/pet_care/assets/images/product4.jpg b/pet_care/assets/images/product4.jpg new file mode 100644 index 0000000..189a297 Binary files /dev/null and b/pet_care/assets/images/product4.jpg differ diff --git a/pet_care/assets/images/product5.jpg b/pet_care/assets/images/product5.jpg new file mode 100644 index 0000000..582aaa2 Binary files /dev/null and b/pet_care/assets/images/product5.jpg differ diff --git a/pet_care/assets/images/slider1.jpg b/pet_care/assets/images/slider1.jpg new file mode 100644 index 0000000..016ab22 Binary files /dev/null and b/pet_care/assets/images/slider1.jpg differ diff --git a/pet_care/assets/images/slider2.jpg b/pet_care/assets/images/slider2.jpg new file mode 100644 index 0000000..84b9450 Binary files /dev/null and b/pet_care/assets/images/slider2.jpg differ diff --git a/pet_care/assets/images/slider3.jpg b/pet_care/assets/images/slider3.jpg new file mode 100644 index 0000000..93bce17 Binary files /dev/null and b/pet_care/assets/images/slider3.jpg differ diff --git a/pet_care/lib/AppBarwidget.dart b/pet_care/lib/AppBarwidget.dart new file mode 100644 index 0000000..eab6d40 --- /dev/null +++ b/pet_care/lib/AppBarwidget.dart @@ -0,0 +1,105 @@ +// Updated AppBarwidget +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:login_page_practice/pages/cartpage.dart'; + +class AppBarwidget extends StatelessWidget { + const AppBarwidget({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final screenWidth = MediaQuery.of(context).size.width; + final screenHeight = MediaQuery.of(context).size.height; + + return Padding( + padding: EdgeInsets.symmetric( + vertical: screenHeight * 0.02, + horizontal: screenWidth * 0.05, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + Navigator.pushNamed(context, "/"); + }, + child: Container( + padding: EdgeInsets.all(screenWidth * 0.015), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(screenWidth * 0.05), + color: Colors.white70, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 10, + offset: Offset(0, 3), + ), + ], + ), + child: Icon( + CupertinoIcons.back, + color: Colors.black, + ), + ), + ), + Container( + padding: EdgeInsets.symmetric( + vertical: screenHeight * 0.01, + horizontal: screenWidth * 0.04, + ), + child: Text( + 'Pet Care App', + style: TextStyle( + color: Colors.black, + fontSize: screenWidth * 0.05, + fontWeight: FontWeight.bold, + ), + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(screenWidth * 0.05), + color: Colors.white70, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 10, + offset: Offset(0, 3), + ), + ], + ), + ), + InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => cartpage(), + ), + ); + }, + child: Container( + padding: EdgeInsets.all(screenWidth * 0.015), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(screenWidth * 0.05), + color: Colors.white70, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 10, + offset: Offset(0, 3), + ), + ], + ), + child: Icon( + CupertinoIcons.cart_fill, + color: Colors.black, + ), + ), + ), + ], + ), + ); + } +} diff --git a/pet_care/lib/ForgotPasswordPage.dart b/pet_care/lib/ForgotPasswordPage.dart new file mode 100644 index 0000000..c8c10f6 --- /dev/null +++ b/pet_care/lib/ForgotPasswordPage.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; +//import 'package:login_page_practice/pages/LoginPage.dart'; + +class ForgotPasswordPage extends StatefulWidget { + const ForgotPasswordPage({Key? key}) : super(key: key); + + @override + State createState() => _ForgotPasswordPageState(); +} + +class _ForgotPasswordPageState extends State { + final _formKey = GlobalKey(); + String? _emailOrPhone; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + title: Text('Forgot Password', style: TextStyle()), + backgroundColor: Colors.teal, + ), + body: SafeArea( + child: Center( + child: SingleChildScrollView( + child: Form( + key: _formKey, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox(height: 10), + Image.asset( + 'lib/images/paw.png', + width: 150, + height: 150, + ), + SizedBox(height: 25), + const Text( + 'RESET YOUR PASSWORD', + style: TextStyle( + color: Colors.teal, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 25), + TextFormField( + keyboardType: TextInputType.emailAddress, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your email or phone number'; + } else if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$') + .hasMatch(value)) { + return 'Please enter a valid email'; + } + return null; + }, + onChanged: (value) { + setState(() { + _emailOrPhone = value; + }); + }, + decoration: InputDecoration( + label: Text( + 'Email', + style: TextStyle(color: Colors.teal), + ), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(5), + borderSide: + BorderSide(color: Colors.cyanAccent.shade400), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.teal), + borderRadius: BorderRadius.circular(5), + ), + hintText: 'Enter Your Email', + fillColor: Colors.grey.shade400, + prefixIcon: Icon(Icons.email_rounded), + prefixIconColor: Colors.cyan[400], + ), + ), + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + // Reset password logic goes here + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + 'Password reset request sent to $_emailOrPhone'), + ), + ); + } + }, + child: Text( + 'Reset Password', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 16), + ), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.teal, + ), + ), + ], + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/pet_care/lib/cartpage.dart b/pet_care/lib/cartpage.dart new file mode 100644 index 0000000..5f487ed --- /dev/null +++ b/pet_care/lib/cartpage.dart @@ -0,0 +1,342 @@ +import 'package:flutter/material.dart'; +import 'package:login_page_practice/pages/AppBarwidget.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'dart:convert'; + + +class cartpage extends StatefulWidget { + final Map? newItem; // Make newItem optional + + const cartpage({Key? key, this.newItem}) : super(key: key); + + @override + State createState() => _CartPageState(); +} + +class _CartPageState extends State { + List> items = []; + late SharedPreferences prefs; // SharedPreferences instance + + @override + void initState() { + super.initState(); + initializeSharedPreferences(); // Initialize SharedPreferences + if (widget.newItem != null) { + items.add(widget.newItem!); // Add newItem to items list if not null + saveItems(); // Save items to SharedPreferences + } + loadItems(); // Load items from SharedPreferences + } + + void initializeSharedPreferences() async { + prefs = await SharedPreferences.getInstance();// Initialize SharedPreferences + loadItems(); + } + + void saveItems() { + prefs.setStringList('items', items.map((item) => item.toString()).toList()); + } + + void loadItems() { + if (prefs != null) { + final List? savedItems = prefs.getStringList('items'); + if (savedItems != null) { + items = savedItems.map((item) => Map.from(json.decode(item))).toList(); + } + } else { + print('SharedPreferences is not initialized.'); + } + } + + + + double getTotalPrice() { + double totalPrice = 0.0; + items.forEach((item) { + totalPrice += item['price'] * item['quantity']; + }); + return totalPrice; + } + + void increaseItemCount(int index) { + setState(() { + items[index]['quantity']++; + saveItems(); // Save items after modification + }); + } + + void decreaseItemCount(int index) { + setState(() { + if (items[index]['quantity'] > 1) { + items[index]['quantity']--; + saveItems(); // Save items after modification + } + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.grey[200], + body: SafeArea( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppBarwidget(), + Padding( + padding: const EdgeInsets.only(top: 20, left: 10, bottom: 10), + child: Text( + 'ORDER LIST', + style: TextStyle( + fontSize: 30, + fontWeight: FontWeight.bold, + ), + ), + ), + ListView.builder( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: items.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 9), + child: Container( + width: MediaQuery.of(context).size.width, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 3, + blurRadius: 4, + offset: Offset(0, 3), + ) + ], + ), + child: Row( + children: [ + Container( + alignment: Alignment.center, + child: Image.asset( + items[index]['image'], + height: 80, + width: 150, + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + items[index]['name'], + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + Text( + '\$${items[index]['price'] * items[index]['quantity']}', + style: TextStyle( + fontSize: 14, + color: Colors.redAccent, + ), + ), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.only(right: 20, top: 13, bottom: 13), + child: Container( + padding: const EdgeInsets.all(5), + decoration: BoxDecoration( + color: Colors.redAccent, + borderRadius: BorderRadius.circular(10), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () => increaseItemCount(index), + child: const Icon( + Icons.add, + color: Colors.white, + size: 20, + ), + ), + Text( + '${items[index]['quantity']}', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + GestureDetector( + onTap: () => decreaseItemCount(index), + child: const Icon( + Icons.minimize, + color: Colors.white, + size: 20, + ), + ), + ], + ), + ), + ), + ], + ), + ), + ); + }, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 30), + child: Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 3, + blurRadius: 10, + offset: Offset(0, 3), + ), + ], + ), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Items', + style: TextStyle(fontSize: 20), + ), + Text( + '${items.fold(0, (prev, item) => prev + item['quantity'] as int)}', + style: TextStyle(fontSize: 20), + ), + ], + ), + ), + Divider(color: Colors.black), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Sub-Total', + style: TextStyle(fontSize: 20), + ), + Text( + '\$${getTotalPrice()}', + style: TextStyle(fontSize: 20), + ), + ], + ), + ), + Divider(color: Colors.black38), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Delivery', + style: TextStyle(fontSize: 20), + ), + Text( + '\$30', // Assuming fixed delivery cost + style: TextStyle(fontSize: 20), + ), + ], + ), + ), + Divider(color: Colors.grey), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Total', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold), + ), + Text( + '\$${getTotalPrice() + 30}', // Total = Sub-Total + Delivery + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold), + ), + ], + ), + ), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 25), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ElevatedButton( + onPressed: () { + setState(() { + items.clear(); // Clear the items list + saveItems(); // Save empty list to clear SharedPreferences + }); + }, + style: ButtonStyle( + backgroundColor: MaterialStatePropertyAll( + Colors.redAccent), + ), + child: Text( + 'Cancel', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + color: Colors.black), + ), + ), + ElevatedButton( + onPressed: () {}, + style: ButtonStyle( + backgroundColor: MaterialStatePropertyAll( + Colors.redAccent), + ), + child: Text( + 'Check Out', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + color: Colors.black), + ), + ), + ], + ), + ), + SizedBox(height: 20), + ], + ), + ), + ), + ), + ); + } +} diff --git a/pet_care/lib/category.dart b/pet_care/lib/category.dart new file mode 100644 index 0000000..17b8418 --- /dev/null +++ b/pet_care/lib/category.dart @@ -0,0 +1,78 @@ +import 'package:flutter/material.dart'; + +class Category extends StatefulWidget { + const Category({Key? key}) : super(key: key); + + @override + State createState() => _CategoryState(); +} + +class _CategoryState extends State { + String selectedCategory = 'cat'; // Default selected category + + @override + Widget build(BuildContext context) { + return Container( + height: 100, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Padding( + padding: EdgeInsets.symmetric(vertical: 15), + child: Row( + children: [ + SizedBox(width: 10), // Add initial padding + buildCategoryItem('Cat', 'cat', 'assets/images/cat1.png'), + SizedBox(width: 10), // Add space between items + buildCategoryItem('Dog', 'dog', 'assets/images/dog1.png'), + SizedBox(width: 10), // Add space at the end + ], + ), + ), + ), + ); + } + + Widget buildCategoryItem(String categoryName, String categoryValue, String imagePath) { + return GestureDetector( + onTap: () { + setState(() { + selectedCategory = categoryValue; + }); + // Add logic to open respective products page based on selected category + // For example: + // if (categoryValue == 'cat') { + // Navigator.pushNamed(context, 'catProducts'); + // } else if (categoryValue == 'dog') { + // Navigator.pushNamed(context, 'dogProducts'); + // } + }, + child: Container( + width: MediaQuery.of(context).size.width * 0.9, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Container( + width: 150, + padding: EdgeInsets.all(13), + decoration: BoxDecoration( + color: selectedCategory == categoryValue ? Colors.tealAccent : Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 10, + offset: Offset(0, 3), + ), + ], + ), + child: Image.asset( + imagePath, + width: 150, + height: 50, + ), + ), + ), + ), + ); + } +} diff --git a/pet_care/lib/itempage.dart b/pet_care/lib/itempage.dart new file mode 100644 index 0000000..995b9d0 --- /dev/null +++ b/pet_care/lib/itempage.dart @@ -0,0 +1,211 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; + +import 'AppBarwidget.dart'; +import 'cartpage.dart'; + +class itempage extends StatefulWidget { + final String productName; + final String productImage; + final String? productDescription; + final double itemPrice; + + const itempage({ + Key? key, + required this.productName, + required this.productImage, + required this.productDescription, + required this.itemPrice, + }) : super(key: key); + + @override + State createState() => _ItemPageState(); +} + +class _ItemPageState extends State { + int itemCount = 1; + late double totalPrice; + + @override + void initState() { + super.initState(); + totalPrice = widget.itemPrice; + } + + void increaseItemCount() { + setState(() { + itemCount++; + totalPrice = itemCount * widget.itemPrice; + }); + } + + void decreaseItemCount() { + setState(() { + if (itemCount > 1) { + itemCount--; + totalPrice = itemCount * widget.itemPrice; + } + }); + } + + void addToOrderList() { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => cartpage(newItem: { + 'name': widget.productName, + 'description': widget.productDescription??'', + 'price': widget.itemPrice, + 'quantity': 1, + 'image': widget.productImage, + }), + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Padding( + padding: const EdgeInsets.only(top: 5), + child: ListView( + children: [ + AppBarwidget(), + Padding( + padding: const EdgeInsets.all(16), + child: Image.asset( + widget.productImage, + height: 400, + width: double.infinity, + fit: BoxFit.contain, + ), + ), + Container( + color: Colors.grey[200], + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.productName, + style: const TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + RatingBar.builder( + initialRating: 4, + minRating: 1, + direction: Axis.horizontal, + itemCount: 5, + itemSize: 18, + itemPadding: + const EdgeInsets.symmetric(horizontal: 4), + itemBuilder: (context, _) => const Icon( + Icons.star, + color: Colors.redAccent, + ), + onRatingUpdate: (index) {}, + ), + Text( + '\$${widget.itemPrice}', + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + ], + ), + const SizedBox(height: 10), + Row( + children: [ + GestureDetector( + onTap: decreaseItemCount, + child: const Icon(Icons.remove_circle_outline), + ), + const SizedBox(width: 10), + Text('$itemCount'), + const SizedBox(width: 10), + GestureDetector( + onTap: increaseItemCount, + child: const Icon(Icons.add_circle_outline), + ), + ], + ), + const SizedBox(height: 20), + Text( + widget.productDescription ?? '', + style: const TextStyle( + fontSize: 16, + ), + ), + const SizedBox(height: 17), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: const [ + Text( + 'Delivery Time:', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + ), + ), + Text( + '30 Minutes', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + ), + ), + ], + ), + ], + ), + ), + ), + ], + ), + ), + bottomNavigationBar: BottomAppBar( + color: Colors.grey[300], + shape: const CircularNotchedRectangle(), + child: Container( + height: 60, + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Total Price: \$${totalPrice.toStringAsFixed(2)}', + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ElevatedButton( + onPressed: addToOrderList, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + ), + child: const Text( + 'Order Now', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/pet_care/lib/main (2).dart b/pet_care/lib/main (2).dart new file mode 100644 index 0000000..0ce0a10 --- /dev/null +++ b/pet_care/lib/main (2).dart @@ -0,0 +1,32 @@ + +import 'package:flutter/material.dart'; +import 'package:login_page_practice/pages/LoginPage.dart'; +import 'package:login_page_practice/pages/cartpage.dart'; +import 'package:login_page_practice/pages/shopping.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatefulWidget { + const MyApp({super.key}); + + @override + State createState() => _MyAppState(); +} +class _MyAppState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: "Pet Care App", + debugShowCheckedModeBanner: false, + theme: ThemeData( + scaffoldBackgroundColor: Colors.white, + ), + routes: { + "shopping" : (context) => shopping(), + "cartpage" : (context) => cartpage(), + }, + ); + } +} diff --git a/pet_care/lib/newitem.dart b/pet_care/lib/newitem.dart new file mode 100644 index 0000000..35157cc --- /dev/null +++ b/pet_care/lib/newitem.dart @@ -0,0 +1,181 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; + +import 'itempage.dart'; + +class newitem extends StatefulWidget { + const newitem({Key? key}) : super(key: key); + + @override + State createState() => _newitemState(); +} + +class _newitemState extends State { + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: SafeArea( + child: Padding( + padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10), + child: Column( + children: [ + // Product 1 + buildProductItem( + productName: 'Bakers Complete Adult Dog with Chicken & Veg 5kg', + productImage: 'assets/images/product5.jpg', + productPrice: 10, + ), + SizedBox(height: 8), + // Product 2 + buildProductItem( + productName: 'Bakers Complete Adult Dog with Chicken & Veg 5kg', + productImage: 'assets/images/product1.png', + productPrice: 10, + ), + SizedBox(height: 8), + // Product 3 + buildProductItem( + productName: 'Bakers Complete Adult Dog with Chicken & Veg 5kg', + productImage: 'assets/images/product2.jpg', + productPrice: 10, + ), + SizedBox(height: 8), + // Product 4 + buildProductItem( + productName: 'Bakers Complete Adult Dog with Chicken & Veg 5kg', + productImage: 'assets/images/product3.jpg', + productPrice: 10, + ), + SizedBox(height: 8), + // Product 5 + buildProductItem( + productName: 'Bakers Complete Adult Dog with Chicken & Veg 5kg', + productImage: 'assets/images/product4.jpg', + productPrice: 10, + ), + SizedBox(height: 8), + ], + ), + ), + ), + ); + } + + Widget buildProductItem({ + required String productName, + required String productImage, + required double productPrice, + }) { + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 3, + blurRadius: 10, + offset: Offset(0, 3), + ), + ], + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + InkWell( + onTap: () { + Navigator.pushNamed(context, "itempage"); + }, + child: Container( + width: MediaQuery.of(context).size.width * 0.3, // Adjusted width + height: 150, + alignment: Alignment.center, + child: Image.asset( + productImage, + fit: BoxFit.cover, + ), + ), + ), + Expanded( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text( + 'Bakers', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 22, + ), + ), + Text( + productName, + style: TextStyle(fontSize: 15), + ), + RatingBar.builder( + initialRating: 4, + minRating: 1, + direction: Axis.horizontal, + itemCount: 5, + itemSize: 18, + itemPadding: EdgeInsets.symmetric(horizontal: 4), + itemBuilder: (context, _) => Icon( + Icons.star, + color: Colors.redAccent, + ), + onRatingUpdate: (index) {}, + ), + Text( + "\$$productPrice", + style: TextStyle( + fontSize: 20, + color: Colors.redAccent, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // Icon( + // Icons.favorite_border, + // color: Colors.redAccent, + // size: 26, + // ), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => itempage( + productName: "Baker", + productImage: productImage, + productDescription: + 'The BakersĀ® Story Our story begins way back in 1851 when Edward Baker set up a family flour business. Fast forward to 1991 when BakersĀ® Complete was launched, because Edward Baker believed that dry dog food should be every bit as tasty as it is nutritious', + itemPrice: productPrice, + ), + ), + ); + }, + child: Icon( + Icons.add_shopping_cart, + color: Colors.redAccent, + size: 26, + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/pet_care/lib/products.dart b/pet_care/lib/products.dart new file mode 100644 index 0000000..d7c2f1c --- /dev/null +++ b/pet_care/lib/products.dart @@ -0,0 +1,132 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class Product { + final String image; + final String title; + final String description; + final double price; + + Product({ + required this.image, + required this.title, + required this.description, + required this.price, + }); +} + +class Products extends StatefulWidget { + const Products({Key? key}) : super(key: key); + + @override + State createState() => _ProductsState(); +} + +class _ProductsState extends State { + List productList = [ + Product( + image: 'assets/images/catproduct1.jpg', + title: 'Fluffy Product', + description: 'New Fluffy Material For Cats', + price: 10.0, + ), + Product( + image: 'assets/images/catproduct1.jpg', + title: 'Fluffy Product', + description: 'New Fluffy Material For Cats', + price: 10.0, + ), + Product( + image: 'assets/images/catproduct1.jpg', + title: 'Fluffy Product', + description: 'New Fluffy Material For Cats', + price: 10.0, + ), + Product( + image: 'assets/images/catproduct1.jpg', + title: 'Fluffy Product', + description: 'New Fluffy Material For Cats', + price: 10.0, + ), + Product( + image: 'assets/images/catproduct1.jpg', + title: 'Fluffy Product', + description: 'New Fluffy Material For Cats', + price: 10.0, + ), + ]; + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: SafeArea( + child: Row( + children: productList.map((product) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 7), + child: SizedBox( + width: MediaQuery.of(context).size.width * 0.35, + child: Card( + elevation: 3, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: Padding( + padding: EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AspectRatio( + aspectRatio: 1.2, // Adjust aspect ratio for responsiveness + child: ClipRRect( + borderRadius: BorderRadius.circular(10), + child: Image.asset( + product.image, + fit: BoxFit.cover, + ), + ), + ), + SizedBox(height: 4), + Text( + product.title, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + Text( + product.description, + style: TextStyle(fontSize: 15), + ), + SizedBox(height: 12), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '\$${product.price}', + style: TextStyle( + fontSize: 17, + color: Colors.redAccent, + fontWeight: FontWeight.bold, + ), + ), + Icon( + Icons.favorite, + color: Colors.redAccent, + size: 16, + ), + ], + ), + ], + ), + ), + ), + ), + ); + }).toList(), + ), + ), + ); + } +} diff --git a/pet_care/lib/shopping.dart b/pet_care/lib/shopping.dart new file mode 100644 index 0000000..887c51a --- /dev/null +++ b/pet_care/lib/shopping.dart @@ -0,0 +1,131 @@ +import 'package:flutter/material.dart'; +import 'package:login_page_practice/pages/products.dart'; +import 'package:login_page_practice/pages/slider.dart'; + +import 'AppBarwidget.dart'; +import 'category.dart'; +import 'newitem.dart'; + +class shopping extends StatefulWidget { + const shopping({Key? key}) : super(key: key); + + @override + State createState() => _ShoppingPageState(); +} + +class _ShoppingPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white70, + body: SafeArea( + child: SingleChildScrollView( // Wrap with SingleChildScrollView + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + AppBarwidget(), + Padding( + padding: EdgeInsets.symmetric( + vertical: 15, + horizontal: 15, + ), + child: Container( + height: 50, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 10, + offset: Offset(0, 3), + ), + ], + ), + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon( + Icons.search, + color: Colors.tealAccent, + ), + Expanded( + child: TextFormField( + decoration: InputDecoration( + hintText: "What You Want to order?", + border: InputBorder.none, + ), + ), + ), + Icon(Icons.filter_list), + ], + ), + ), + ), + ), + SizedBox(height: 20), + // Padding( + // padding: EdgeInsets.only(bottom: 20, left: 13), + // child: Text( + // 'Top Offers', + // style: TextStyle( + // fontWeight: FontWeight.bold, + // fontSize: 30, + // color: Colors.black, + // ), + // ), + // ), + + SliderWidget(), + SizedBox(height: 20), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Text( + 'Categories', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + color: Colors.black, + ), + ), + ), + Category(), + SizedBox(height: 20), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Text( + 'Popular Items', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + color: Colors.black, + ), + ), + ), + Products(), + SizedBox(height: 20), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Text( + 'New Items', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + color: Colors.black, + ), + ), + ), + newitem(), + SizedBox(height: 20), // Add additional spacing at the end + ], + ), + ), + ), + ); + } +} diff --git a/pet_care/lib/slider.dart b/pet_care/lib/slider.dart new file mode 100644 index 0000000..40eeed8 --- /dev/null +++ b/pet_care/lib/slider.dart @@ -0,0 +1,55 @@ +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter/material.dart'; + +class SliderWidget extends StatefulWidget { + const SliderWidget({Key? key}) : super(key: key); + + @override + State createState() => _SliderWidgetState(); +} + +class _SliderWidgetState extends State { + final List imagePaths = [ + 'lib/images/slider1.jpg', + 'lib/images/slider2.jpg', + 'lib/images/slider3.jpg', + ]; + + @override + Widget build(BuildContext context) { + return Container( + height: 200, + child: CarouselSlider( + items: imagePaths.map((imagePath) => _buildSliderItem(imagePath)).toList(), + options: CarouselOptions( + height: 200, + aspectRatio: 16 / 9, + viewportFraction: 0.8, + initialPage: 0, + enableInfiniteScroll: true, + autoPlay: true, + autoPlayInterval: const Duration(seconds: 3), + autoPlayAnimationDuration: const Duration(milliseconds: 800), + autoPlayCurve: Curves.fastOutSlowIn, + enlargeCenterPage: true, + scrollDirection: Axis.horizontal, + ), + ), + ); + } + + Widget _buildSliderItem(String imagePath) { + return Container( + width: MediaQuery.of(context).size.width, + margin: const EdgeInsets.symmetric(horizontal: 5.0), + decoration: BoxDecoration( + color: Colors.grey, + borderRadius: BorderRadius.circular(15.0), + image: DecorationImage( + image: AssetImage(imagePath), + fit: BoxFit.cover, + ), + ), + ); + } +}