Description

Masdul widget help in simplifying code for some complicated widget.

Features

  • Search Page
  • Menu drawer / Menu Bottom Sheet / Menu Icon

Search Page

Search Page

import 'package:faker/faker.dart';
import 'package:flutter/material.dart';
import 'package:masdul_mobile/arguments/search_page_arguments.dart';
import 'package:masdul_mobile/models/search_page_widget_model.dart';
import 'package:masdul_mobile/search_page_widget.dart';

class SearchPageSample extends StatefulWidget {
  const SearchPageSample({super.key});

  @override
  State<SearchPageSample> createState() => _SearchPageSampleState();
}

class _SearchPageSampleState extends State<SearchPageSample> {
  var faker = Faker();
  late List<SearchPageWidgetModel<SearchPageSampleModel>> sampleData;
  late List<SearchPageWidgetModel<SearchPageSampleModel>> searchData;

  @override
  void initState() {
    sampleData = [];
    for (var i = 0; i < 5; i++) {
      var faker = Faker();
      var sData = SearchPageSampleModel(
        id: faker.guid.random.toString(),
        address: faker.address.city(),
        age: 23,
        name: faker.person.name(),
        salary: faker.randomGenerator.integer(1000000, min: 50000),
      );
      sampleData.add(SearchPageWidgetModel(
        title: sData.name,
        description: sData.address,
        value: sData,
      ));
      searchData = sampleData;
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Search Page"),
      ),
      body: Container(
        padding: const EdgeInsets.only(left: 20, right: 20, top: 20),
        child: SearchPageWidget<SearchPageSampleModel>(
          args: SearchPageArguments<SearchPageSampleModel>(
            data: searchData,
            color: Colors.blue,
            hint: "Search ...",
            title: "Search Employee",
            // isLocalSearch: true,
            onTextChanged: (text, localSearch) {
              searchData = sampleData
                  .where(
                    (element) => element.title
                        .toLowerCase()
                        .contains(text.trim().toLowerCase()),
                  )
                  .toList();
              setState(() {});
            },
          ),
        ),
      ),
    );
  }
}

class SearchPageSampleModel {
  final String id;
  final String name;
  final String address;
  final int age;
  final int salary;

  SearchPageSampleModel({
    required this.id,
    required this.name,
    required this.address,
    required this.age,
    required this.salary,
  });
}

Menu icons Menu drawer Menu bottom_sheet

import 'package:faker/faker.dart';
import 'package:flutter/material.dart';
import 'package:masdul_mobile/arguments/menu_widget_arguments.dart';
import 'package:masdul_mobile/masdul_widget_mobile.dart';
import 'package:masdul_mobile/models/menu_widget_model.dart';
import 'package:masdul_widget/circle_image.dart';
import 'package:masdul_widget/popup_widget.dart';
import 'package:masdul_widget/rounded_image.dart';

class MenuSample extends StatefulWidget {
  const MenuSample({super.key});

  @override
  State<MenuSample> createState() => _MenuSampleState();
}

class _MenuSampleState extends State<MenuSample> with TickerProviderStateMixin {
  var faker = Faker();
  late List<MenuWidgetList<String>> sampleData;
  late List<MenuWidgetIconList<String>> sampleDataIcon;
  late AnimationController controller;
  final GlobalKey<ScaffoldState> _scaffoldkey = GlobalKey<ScaffoldState>();

  @override
  void initState() {
    sampleData = [];
    for (var i = 0; i < 7; i++) {
      var data = MenuWidgetList<String>(
        title: faker.person.name(),
        description: faker.address.city(),
        leading: CircleImage(
          size: 40,
          image: Image.network(faker.image.image()),
        ),
        trailing: const Icon(
          Icons.keyboard_arrow_right,
        ),
        value: "menu $i",
        onTap: (value) {
          PopupWidget.alert(
            context,
            title: value ?? "-",
          );
        },
      );
      sampleData.add(data);
    }
    sampleDataIcon = sampleData.map((e) {
      return MenuWidgetIconList<String>(
        title: e.title,
        onTap: e.onTap,
        value: e.value,
        image: Image.network(faker.image.image()),
        imageRadius: 20,
      );
    }).toList();

    controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 200),
    );
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldkey,
      appBar: AppBar(
        title: const Text("Menu Sample"),
        actions: [
          IconButton(
            onPressed: () {
              _scaffoldkey.currentState!.showBottomSheet<void>(
                (BuildContext context) {
                  return SizedBox(
                    // height: MediaQuery.of(context).size.height,
                    child: MenuBottomSheetWidget(
                      args: MenuWidgetArguments(
                        header: MenuWidgetHeader(
                          color: Theme.of(context).primaryColor,
                          title: "App Name",
                          description: "Description",
                          onTap: () {
                            PopupWidget.alert(
                              context,
                              title: "App Name",
                              content: "Description",
                            );
                          },
                          leading: CircleImage(
                            size: 60,
                            image: Image.network(faker.image.image()),
                          ),
                          trailing: const Icon(
                            Icons.keyboard_arrow_down,
                          ),
                        ),
                        list: sampleData,
                      ),
                    ),
                  );
                },
              );
            },
            icon: const Icon(Icons.more_vert),
          )
        ],
      ),
      drawer: MenuDrawerWidget<String>(
        args: MenuWidgetArguments(
          header: MenuWidgetHeader(
            color: Theme.of(context).primaryColor,
            title: "App Name",
            description: "Description",
            onTap: () {
              PopupWidget.alert(
                context,
                title: "App Name",
                content: "Description",
              );
            },
            leading: CircleImage(
              size: 60,
              image: Image.network(faker.image.image()),
            ),
            trailing: const Icon(
              Icons.keyboard_arrow_down,
            ),
          ),
          list: sampleData,
        ),
      ),
      body: Container(
        padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
        child: MenuIconWidget(
          args: MenuWidgetIconArguments(
            itemWidth: 60,
            list: sampleDataIcon,
            maxItemInRow: 5,
            containerWidth: MediaQuery.of(context).size.width - 40,
            header: MenuWidgetHeader(
              color: Theme.of(context).primaryColor,
              title: "App Name",
              description: "Description",
              onTap: () {
                PopupWidget.alert(
                  context,
                  title: "App Name",
                  content: "Description",
                );
              },
              leading: CircleImage(
                size: 60,
                image: Image.network(faker.image.image()),
              ),
              trailing: const Icon(
                Icons.keyboard_arrow_down,
              ),
            ),
          ),
        ),
        // _renderMenu(
        //   maxItemInRow: 5,
        //   itemWidth: 60,
        //   items: sampleDataIcon,
        //   containerWidth: MediaQuery.of(context).size.width - 40,
        // ),
      ),
    );
  }
}

Login Page

Login

LoginPageWidget(
  args: LoginPageArguments(
    errorMessage: "test",
    color: customblue,
    usernameLabel: "Username",
    passwordLabel: "Password",
    submitLabel: "Login",
    logo: dul.CircleImage(
      image: Image.network( Faker().image.image()),
      size: 150,
    ),
    registerLabel:
        "Didn't have an account yet? Register now!",
    forgotLabel:
        "Forgot password?",
    onForgot: () {
      Navigator.of(context).pushNamed(
        Routes.forgot,
      );
    },
    onRegister: () {
      Navigator.of(context).pushNamed(
        Routes.register,
      );
    },
    onSubmit: (
        {required String password,
        required String username}) {
          
        },
  ),
)

Register Page

Register

dulm.RegisterPageWidget(
  args: RegisterPageArguments(
    errorMessage: null,
    color: customblue,
    usernameLabel: "Username",
    passwordLabel: "Password",
    submitLabel: "Register",
    extendFields: [
      RegisterExtendTextField(
        label: "Address",
        keyboardType: TextInputType.streetAddress,
        controller: addressController,
        obscureText: false,
      ),
      RegisterExtendDropdown(
        label: "Marital Status",
        items: const [
          DropdownMenuItem(
            value: "married",
            child: Text("Married"),
          ),
          DropdownMenuItem(
            value: "divorced",
            child: Text("Divorced"),
          ),
          DropdownMenuItem(
            value: "separated",
            child: Text("Separated"),
          ),
          DropdownMenuItem(
            value: "widowed",
            child: Text("Widowed"),
          ),
          DropdownMenuItem(
            value: "never",
            child: Text("Never Married"),
          ),
        ],
      ),
      RegisterExtendRadio(
        label: "Gender",
        items: const {
          "Male":"M",
          "Female":"F",
        },
      ),
      RegisterExtendCheck(
        label: "Hobbies",
        items: const {
          "Otomotif":"otomotif",
          "Computer":"computer",
        },
      ),
    ],
    logo: dul.CircleImage(
      image: Image.network(Faker().image.image()),
      size: 80,
    ),
    onSubmit: (
        {required String password,
        required String username,
        required Map<String, dynamic> extendData}) {},
  ),
)

Forgot Page

forgot

ForgotPageWidget(
  args: ForgotPageArguments(
    errorMessage: null,
    color: customblue,
    isPhone: true,
    label: "Input your phone",
    submitLabel: "Submit",
    logo: dul.CircleImage(
      image: Image.network(Faker().image.image()),
      size: 150,
    ),
    onSubmit: ({required String emailOrPhone}) {},
  ),
),

OTP Page

otp

dulm.OtpVerificationPageWidget(
  args: OtpVerificationPageArguments(
    errorMessage: null,
    color: customblue,
    label: "Verify your account",
    hint: "Otp Code",
    submitLabel: "Submit",
    keyboardType: TextInputType.number,
    logo: dul.CircleImage(
      image: Image.network(Faker().image.image()),
      size: 150,
    ),
    onSubmit: ({required String otp}) {},
  ),
)