Stationary Shop Bill App Using Flutter



In this tutorial, we'll be creating a Stationary App application using Firebase in Flutter,

Stationary app are essential app for keeping Stationary and study materials organized. Our app creates a scrollable Stationary list , allowing users to save Stationary via a text field. Stationary are dynamically displayed within containers. Users can scroll through the list as needed. Users can edit , delete their Stationary details and can find the total also. By the end of this tutorial, you'll have a functional Stationary List app that you can run on both Android and iOS devices.


Source Code for the main.dart file




Add the following Code inside your main.dart file :


             
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';


void main() async{
    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp();
    runApp(const MyApp());
}

class MyApp extends StatelessWidget {
    const MyApp({super.key});

    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home:HomePage(),
    );
    }
}
class HomePage extends StatefulWidget {
    const HomePage({super.key});

    @override
    State createState() => _HomePageState();
}

class _HomePageState extends State {

// text fields' controllers
    final TextEditingController _nameController = TextEditingController();
    final TextEditingController _priceController = TextEditingController();
    final TextEditingController _nameController1 = TextEditingController();
    final TextEditingController _priceController1 = TextEditingController();

    final CollectionReference item =
    FirebaseFirestore.instance.collection('items');

    Future _calculateTotalPrice() async {
    QuerySnapshot querySnapshot = await item.get();
    int totalPrice = 0;

    querySnapshot.docs.forEach((itprice) {
        totalPrice = totalPrice + (itprice['price'] as num).toInt();
    });

    showDialog(
        context: context,
        builder: (BuildContext context) {
        return AlertDialog(
            title: Text('Total Price'),
            content: Text('\u{20B9}${totalPrice.toInt()}'), // Format total price with two decimal places
            actions: [
            TextButton(
                onPressed: () {
                Navigator.of(context).pop();
                },
                child: Text('Close'),
            ),
            ],
        );
        },
    );
    }



    Future< void> _create() async {

    await showModalBottomSheet(
        isScrollControlled: true,
        context: context,
        builder: (BuildContext ctx) {
            return Padding(
            padding: EdgeInsets.only(
                top: 20,
                left: 20,
                right: 20,
                bottom: MediaQuery.of(ctx).viewInsets.bottom + 20),
            child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                SizedBox(
                    height: 20,
                ),
                Text('Add Items',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                        fontSize: 19,
                        fontWeight: FontWeight.w600
                    ),),
                SizedBox(
                    height: 20,
                ),
                TextField(
                    controller: _nameController1,
                    decoration: const InputDecoration(labelText: 'Name'),
                ),
                TextField(
                    controller: _priceController1,
                    decoration: const InputDecoration(labelText: 'Price'),
                ),
                const SizedBox(
                    height: 20,
                ),
                ElevatedButton(
                    style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.deepPurpleAccent
                    ),
                    child: const Text('Create'),
                    onPressed: () async
                    {
                    final String name = _nameController1.text;
                    final int? price = int.tryParse(_priceController1.text);
                    if(price!=null)
                        {
                        await item.add({"name": name, "price": price});
                        _nameController1.text = '';
                        _priceController1.text = '';
                        Navigator.of(context).pop();
                    }
                    },
                )
                ],
            ),
            );

        });
    }
    Future< void> _update([DocumentSnapshot? documentSnapshot]) async {
    if (documentSnapshot != null) {

        _nameController.text = documentSnapshot['name'];
        _priceController.text = documentSnapshot['price'].toString();

    }

    await showModalBottomSheet(
        isScrollControlled: true,
        context: context,
        builder: (BuildContext ctx) {
            return Padding(
            padding: EdgeInsets.only(
                top: 20,
                left: 20,
                right: 20,
                bottom: MediaQuery.of(ctx).viewInsets.bottom + 20),
            child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                SizedBox(
                    height: 20,
                ),
                Text('Update Item',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                        fontSize: 19,
                        fontWeight: FontWeight.w600,


                    ),),
                SizedBox(
                    height: 20,
                ),
                TextField(
                    controller: _nameController,
                    decoration: const InputDecoration(labelText: 'Name'),
                ),
                TextField(
                    controller: _priceController,
                    decoration: const InputDecoration(labelText: 'Price'),
                ),
                const SizedBox(
                    height: 20,
                ),
                ElevatedButton(
                    style: ElevatedButton.styleFrom(
                        backgroundColor: Colors.deepPurpleAccent
                    ),
                    child: const Text( 'Update'),
                    onPressed: () async
                    {
                    final String name = _nameController.text;
                    final int? price = int.tryParse(_priceController.text);
                    if(price!=null)
                    {
                        await item.doc(documentSnapshot!.id).update({"name": name, "price": price});
                        _nameController.text = '';
                        _priceController.text = '';
                        Navigator.of(context).pop();
                    }
                    },
                )
                ],
            ),
            );
        });
    }

    Future< void> _delete(String productId) async {
    await item.doc(productId).delete();

    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
        backgroundColor: Colors.deepPurpleAccent,
        content: Text('You have successfully deleted an item')));
    }

    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
        backgroundColor: Colors.deepPurpleAccent,
        title: Text('Stationary  Items'),
        centerTitle: true,
        elevation: 0.0,
    ),

        body:
        Padding(
        padding: const EdgeInsets.only(left: 10, right: 10),
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
            Expanded(
                flex: 8,
                child: StreamBuilder(

                stream: item.snapshots(),
                builder: (context, AsyncSnapshot streamSnapshot) {
                    if (streamSnapshot.hasData) {
                    return ListView.builder(
                        itemCount: streamSnapshot.data!.docs.length,
                        itemBuilder: (context, index) {

                        final DocumentSnapshot documentSnapshot =
                        streamSnapshot.data!.docs[index];
                        return Card(

                            margin: const EdgeInsets.all(10),
                            child: ListTile(
                            title: Text(documentSnapshot['name'],style: TextStyle(
                                fontWeight: FontWeight.w600,
                                fontSize: 17
                            ),),
                            // subtitle: Text((documentSnapshot['price']).toString()
                                subtitle: Text('\u{20B9}${(documentSnapshot['price']).toString()}',
                                style: TextStyle(
                                fontSize: 15,
                                fontWeight: FontWeight.w500
                            ),
                                ),

                            trailing: SizedBox(
                                width: 100,
                                child: Row(
                                children: [
                                    IconButton(
                                        icon: const Icon(Icons.edit),
                                        color: Colors.yellow[800],
                                        onPressed: ()
                                        {
                                        _update(documentSnapshot);
                                        }

                                    ),
                                    IconButton(
                                        icon: const Icon(Icons.delete),
                                        color: Colors.red,
                                        onPressed: ()
                                        {
                                        _delete(documentSnapshot.id);
                                        }
                                    ),
                                ],
                                ),
                            ),
                            ),
                        );
                        },
                    );
                    }

                    return const Center(
                    child: CircularProgressIndicator(),
                    );
                },
                ),
            ),
            Expanded(

                child: Container(

                    child:
                TextButton(
                    onPressed: ()
                    {
_calculateTotalPrice();
                    },
                    child: Text('Total',
                    style: TextStyle(
                    fontSize: 24,
                    color: Colors.deepPurpleAccent,

                    ),),
                )


                    // color: Colors.deepPurpleAccent,
                )
            )
            ],
        ),
        ),
// Add new product
        floatingActionButton: FloatingActionButton(
        backgroundColor: Colors.deepPurpleAccent,
        onPressed: (){
            _create();
        },
        child: const Icon(Icons.add),

        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,


    );
    }
}
                
                
                
                
                
                
                
             
            


The Output is shown below :








Contact Us

REACH US

SERVICES

  • CODING
  • ON-LINE PREPARATION
  • JAVA & PYTHON

ADDRESS

B-54, Krishna Bhawan, Parag Narain Road, Near Butler Palace Colony Lucknow
Contact:+ 919839520987
Email:info@alexsir.com