├── ios
├── Runner
│ ├── Runner-Bridging-Header.h
│ ├── Assets.xcassets
│ │ ├── LaunchImage.imageset
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ ├── README.md
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ └── Info.plist
├── Flutter
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── AppFrameworkInfo.plist
├── Runner.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ └── project.pbxproj
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── WorkspaceSettings.xcsettings
│ │ └── IDEWorkspaceChecks.plist
├── RunnerTests
│ └── RunnerTests.swift
├── .gitignore
└── Podfile
├── web
├── favicon.png
├── icons
│ ├── Icon-192.png
│ ├── Icon-512.png
│ ├── Icon-maskable-192.png
│ └── Icon-maskable-512.png
├── manifest.json
└── index.html
├── assets
├── images
│ ├── f1.jpeg
│ ├── f2.jpeg
│ ├── f3.jpeg
│ ├── f4.jpeg
│ ├── f5.jpeg
│ ├── f6.jpeg
│ ├── f7.jpeg
│ ├── f8.jpeg
│ ├── logo.png
│ ├── manage_printer.png
│ ├── manage_product.png
│ └── manage_printerx.png
└── icons
│ ├── done.svg
│ ├── dashboard.svg
│ ├── print.svg
│ ├── image.svg
│ ├── orders.svg
│ ├── payments.svg
│ ├── home.svg
│ ├── history.svg
│ ├── debit.svg
│ ├── snack.svg
│ ├── delete.svg
│ ├── cash.svg
│ ├── all_categories.svg
│ ├── qr_code.svg
│ ├── food.svg
│ └── drink.svg
├── android
├── gradle.properties
├── app
│ ├── src
│ │ ├── main
│ │ │ ├── res
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── drawable
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable-v21
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── values
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-night
│ │ │ │ │ └── styles.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── fic11_starter_pos
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── AndroidManifest.xml
│ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ └── profile
│ │ │ └── AndroidManifest.xml
│ └── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── .gitignore
├── build.gradle
└── settings.gradle
├── lib
├── presentation
│ ├── manage
│ │ ├── models
│ │ │ ├── printer_model.dart
│ │ │ └── cwb_print.dart
│ │ ├── widgets
│ │ │ ├── menu_printer_content.dart
│ │ │ ├── menu_printer_button.dart
│ │ │ └── change_price_bottom_sheet.dart
│ │ └── pages
│ │ │ ├── manage_menu_page.dart
│ │ │ └── manage_printer_page.dart
│ ├── home
│ │ ├── models
│ │ │ ├── product_category.dart
│ │ │ └── product_model.dart
│ │ ├── widgets
│ │ │ ├── product_empty.dart
│ │ │ ├── nav_item.dart
│ │ │ └── product_card.dart
│ │ └── pages
│ │ │ ├── dashboard_page.dart
│ │ │ └── home_page.dart
│ ├── order
│ │ ├── models
│ │ │ └── order_model.dart
│ │ ├── widgets
│ │ │ ├── process_button.dart
│ │ │ ├── payment_qris_dialog.dart
│ │ │ ├── payment_cash_dialog.dart
│ │ │ ├── payment_success_dialog.dart
│ │ │ └── order_card.dart
│ │ └── pages
│ │ │ └── orders_page.dart
│ └── auth
│ │ └── pages
│ │ └── login_page.dart
├── core
│ ├── extensions
│ │ ├── string_ext.dart
│ │ ├── int_ext.dart
│ │ ├── date_time_ext.dart
│ │ └── build_context_ext.dart
│ ├── components
│ │ ├── spaces.dart
│ │ ├── search_input.dart
│ │ ├── custom_dropdown.dart
│ │ ├── custom_text_field.dart
│ │ ├── tab_custom.dart
│ │ ├── menu_button.dart
│ │ ├── image_picker_widget.dart
│ │ └── buttons.dart
│ ├── constants
│ │ └── colors.dart
│ └── assets
│ │ └── assets.gen.dart
└── main.dart
├── README.md
├── .gitignore
├── test
└── widget_test.dart
├── analysis_options.yaml
├── .metadata
└── pubspec.yaml
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/web/favicon.png
--------------------------------------------------------------------------------
/assets/images/f1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/f1.jpeg
--------------------------------------------------------------------------------
/assets/images/f2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/f2.jpeg
--------------------------------------------------------------------------------
/assets/images/f3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/f3.jpeg
--------------------------------------------------------------------------------
/assets/images/f4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/f4.jpeg
--------------------------------------------------------------------------------
/assets/images/f5.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/f5.jpeg
--------------------------------------------------------------------------------
/assets/images/f6.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/f6.jpeg
--------------------------------------------------------------------------------
/assets/images/f7.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/f7.jpeg
--------------------------------------------------------------------------------
/assets/images/f8.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/f8.jpeg
--------------------------------------------------------------------------------
/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/logo.png
--------------------------------------------------------------------------------
/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx4G
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/assets/images/manage_printer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/manage_printer.png
--------------------------------------------------------------------------------
/assets/images/manage_product.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/manage_product.png
--------------------------------------------------------------------------------
/web/icons/Icon-maskable-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/web/icons/Icon-maskable-192.png
--------------------------------------------------------------------------------
/web/icons/Icon-maskable-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/web/icons/Icon-maskable-512.png
--------------------------------------------------------------------------------
/assets/images/manage_printerx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/assets/images/manage_printerx.png
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/is2024/flutter-kedai-starter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/fic11_starter_pos/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.fic11_starter_pos
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/lib/presentation/manage/models/printer_model.dart:
--------------------------------------------------------------------------------
1 | class PrinterModel {
2 | final String name;
3 | final int address;
4 |
5 | PrinterModel({
6 | required this.name,
7 | required this.address,
8 | });
9 | }
10 |
--------------------------------------------------------------------------------
/lib/presentation/home/models/product_category.dart:
--------------------------------------------------------------------------------
1 | enum ProductCategory {
2 | none('None'),
3 | drink('Minuman'),
4 | food('Makanan'),
5 | snack('Snack');
6 |
7 | final String value;
8 | const ProductCategory(this.value);
9 | }
10 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
6 |
--------------------------------------------------------------------------------
/lib/core/extensions/string_ext.dart:
--------------------------------------------------------------------------------
1 | extension StringExt on String {
2 | int get toIntegerFromText {
3 | final cleanedText = replaceAll(RegExp(r'[^0-9]'), '');
4 | final parsedValue = int.tryParse(cleanedText) ?? 0;
5 | return parsedValue;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/lib/core/extensions/int_ext.dart:
--------------------------------------------------------------------------------
1 | import 'package:intl/intl.dart';
2 |
3 | extension IntegerExt on int {
4 | String get currencyFormatRp => NumberFormat.currency(
5 | locale: 'id',
6 | symbol: 'Rp. ',
7 | decimalDigits: 0,
8 | ).format(this);
9 | }
10 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/assets/icons/done.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/assets/icons/dashboard.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/ios/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/lib/presentation/order/models/order_model.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:fic11_starter_pos/core/extensions/int_ext.dart';
4 |
5 | class OrderModel {
6 | final String image;
7 | final String name;
8 | final int price;
9 | int quantity;
10 |
11 | OrderModel({
12 | required this.image,
13 | required this.name,
14 | required this.price,
15 | this.quantity = 1,
16 | });
17 |
18 | String get priceFormat => price.currencyFormatRp;
19 | }
20 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/lib/core/components/spaces.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class SpaceHeight extends StatelessWidget {
4 | final double height;
5 | const SpaceHeight(this.height, {super.key});
6 |
7 | @override
8 | Widget build(BuildContext context) => SizedBox(height: height);
9 | }
10 |
11 | class SpaceWidth extends StatelessWidget {
12 | final double width;
13 | const SpaceWidth(this.width, {super.key});
14 |
15 | @override
16 | Widget build(BuildContext context) => SizedBox(width: width);
17 | }
18 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/assets/icons/print.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/lib/presentation/home/models/product_model.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:fic11_starter_pos/core/extensions/int_ext.dart';
3 |
4 | import 'product_category.dart';
5 |
6 | class ProductModel {
7 | final String image;
8 | final String name;
9 | final ProductCategory category;
10 | final int price;
11 | final int stock;
12 |
13 | ProductModel({
14 | required this.image,
15 | required this.name,
16 | required this.category,
17 | required this.price,
18 | required this.stock,
19 | });
20 |
21 | String get priceFormat => price.currencyFormatRp;
22 | }
23 |
--------------------------------------------------------------------------------
/lib/core/extensions/date_time_ext.dart:
--------------------------------------------------------------------------------
1 | extension DateTimeExt on DateTime {
2 | String toFormattedTime() {
3 | final List monthNames = [
4 | 'Januari',
5 | 'Februari',
6 | 'Maret',
7 | 'April',
8 | 'Mei',
9 | 'Juni',
10 | 'Juli',
11 | 'Agustus',
12 | 'September',
13 | 'Oktober',
14 | 'November',
15 | 'Desember'
16 | ];
17 |
18 | final int hour12 = hour % 12;
19 | final String monthName = monthNames[month - 1];
20 |
21 | return '$day $monthName, ${hour12.toString().padLeft(2, '0')}:${minute.toString().padLeft(2, '0')}';
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/assets/icons/image.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flutter_kedai_starter
2 |
3 | A new Flutter project.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
13 |
14 | For help getting started with Flutter development, view the
15 | [online documentation](https://docs.flutter.dev/), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 | # flutter-kedai
18 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.7.10'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
10 | }
11 | }
12 |
13 | allprojects {
14 | repositories {
15 | google()
16 | mavenCentral()
17 | }
18 | }
19 |
20 | rootProject.buildDir = '../build'
21 | subprojects {
22 | project.buildDir = "${rootProject.buildDir}/${project.name}"
23 | }
24 | subprojects {
25 | project.evaluationDependsOn(':app')
26 | }
27 |
28 | tasks.register("clean", Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/assets/icons/orders.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | **/doc/api/
26 | **/ios/Flutter/.last_build_id
27 | .dart_tool/
28 | .flutter-plugins
29 | .flutter-plugins-dependencies
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Symbolication related
35 | app.*.symbols
36 |
37 | # Obfuscation related
38 | app.*.map.json
39 |
40 | # Android Studio will place build artifacts here
41 | /android/app/debug
42 | /android/app/profile
43 | /android/app/release
44 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 11.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/lib/core/constants/colors.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class AppColors {
4 | /// primary = #3949AB
5 | static const Color primary = Color(0xff3949AB);
6 |
7 | /// grey = #B7B7B7
8 | static const Color grey = Color(0xffB7B7B7);
9 |
10 | /// light = #F8F5FF
11 | static const Color light = Color(0xffF8F5FF);
12 |
13 | /// light = #C7D0EB
14 | static const Color blueLight = Color(0xffC7D0EB);
15 |
16 | /// black = #000000
17 | static const Color black = Color(0xff000000);
18 |
19 | /// white = #FFFFFF
20 | static const Color white = Color(0xffFFFFFF);
21 |
22 | /// green = #50C474
23 | static const Color green = Color(0xff50C474);
24 |
25 | /// red = #F4261A
26 | static const Color red = Color(0xffF4261A);
27 |
28 | /// card = #E5E5E5
29 | static const Color card = Color(0xffE5E5E5);
30 |
31 | /// disabled = #C8D1E1
32 | static const Color disabled = Color(0xffC8D1E1);
33 | }
34 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | def flutterSdkPath = {
3 | def properties = new Properties()
4 | file("local.properties").withInputStream { properties.load(it) }
5 | def flutterSdkPath = properties.getProperty("flutter.sdk")
6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7 | return flutterSdkPath
8 | }
9 | settings.ext.flutterSdkPath = flutterSdkPath()
10 |
11 | includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
12 |
13 | repositories {
14 | google()
15 | mavenCentral()
16 | gradlePluginPortal()
17 | }
18 |
19 | plugins {
20 | id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
21 | }
22 | }
23 |
24 | plugins {
25 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
26 | id "com.android.application" version "7.3.0" apply false
27 | }
28 |
29 | include ":app"
30 |
--------------------------------------------------------------------------------
/assets/icons/payments.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/assets/icons/home.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/lib/presentation/home/widgets/product_empty.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../../core/assets/assets.gen.dart';
4 | import '../../../core/components/spaces.dart';
5 | import '../../../core/constants/colors.dart';
6 |
7 |
8 | class ProductEmpty extends StatelessWidget {
9 | const ProductEmpty({super.key});
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return Center(
14 | child: Column(
15 | mainAxisSize: MainAxisSize.max,
16 | mainAxisAlignment: MainAxisAlignment.center,
17 | children: [
18 | Assets.icons.orders.svg(width: 114.0),
19 | const SpaceHeight(4.0),
20 | const Text(
21 | 'Belum ada Produk',
22 | textAlign: TextAlign.center,
23 | style: TextStyle(
24 | fontSize: 16,
25 | color: AppColors.grey,
26 | ),
27 | ),
28 | ],
29 | ),
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/assets/icons/history.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/assets/icons/debit.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/assets/icons/snack.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fic11_starter_pos",
3 | "short_name": "fic11_starter_pos",
4 | "start_url": ".",
5 | "display": "standalone",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "A new Flutter project.",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/Icon-192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/Icon-512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | },
22 | {
23 | "src": "icons/Icon-maskable-192.png",
24 | "sizes": "192x192",
25 | "type": "image/png",
26 | "purpose": "maskable"
27 | },
28 | {
29 | "src": "icons/Icon-maskable-512.png",
30 | "sizes": "512x512",
31 | "type": "image/png",
32 | "purpose": "maskable"
33 | }
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/assets/icons/delete.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility in the flutter_test package. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:fic11_starter_pos/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(const MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/constants/colors.dart';
2 | import 'package:fic11_starter_pos/presentation/auth/pages/login_page.dart';
3 | import 'package:fic11_starter_pos/presentation/home/pages/dashboard_page.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:google_fonts/google_fonts.dart';
6 |
7 | void main() {
8 | runApp(const MyApp());
9 | }
10 |
11 | class MyApp extends StatelessWidget {
12 | const MyApp({super.key});
13 |
14 | @override
15 | Widget build(BuildContext context) {
16 | return MaterialApp(
17 | title: 'Flutter Starter Kedai',
18 | theme: ThemeData(
19 | colorScheme: ColorScheme.fromSeed(seedColor: AppColors.primary),
20 | useMaterial3: true,
21 | textTheme: GoogleFonts.quicksandTextTheme(
22 | Theme.of(context).textTheme,
23 | ),
24 | appBarTheme: AppBarTheme(
25 | color: AppColors.white,
26 | elevation: 0,
27 | titleTextStyle: GoogleFonts.quicksand(
28 | color: AppColors.primary,
29 | fontSize: 16.0,
30 | fontWeight: FontWeight.w500,
31 | ),
32 | iconTheme: const IconThemeData(
33 | color: AppColors.primary,
34 | ),
35 | ),
36 | ),
37 | home: const LoginPage(),
38 | );
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/assets/icons/cash.svg:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/lib/core/extensions/build_context_ext.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | extension BuildContextExt on BuildContext {
4 | double get deviceHeight => MediaQuery.of(this).size.height;
5 |
6 | double get deviceWidth => MediaQuery.of(this).size.width;
7 | }
8 |
9 | extension NavigatorExt on BuildContext {
10 | void pop([T? result]) {
11 | Navigator.pop(this, result);
12 | }
13 |
14 | void popToRoot() {
15 | Navigator.popUntil(this, (route) => route.isFirst);
16 | }
17 |
18 | Future push(Widget widget, [String? name]) async {
19 | return Navigator.push(
20 | this,
21 | MaterialPageRoute(
22 | builder: (context) => widget,
23 | settings: RouteSettings(name: name),
24 | ),
25 | );
26 | }
27 |
28 | Future pushReplacement(
29 | Widget widget) async {
30 | return Navigator.pushReplacement(
31 | this,
32 | MaterialPageRoute(builder: (context) => widget),
33 | );
34 | }
35 |
36 | Future pushAndRemoveUntil(
37 | Widget widget, bool Function(Route route) predicate) async {
38 | return Navigator.pushAndRemoveUntil(
39 | this,
40 | MaterialPageRoute(builder: (context) => widget),
41 | predicate,
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/presentation/manage/widgets/menu_printer_content.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
3 |
4 | import '../../../core/constants/colors.dart';
5 | import '../models/printer_model.dart';
6 |
7 | class MenuPrinterContent extends StatelessWidget {
8 | final BluetoothInfo data;
9 | final bool isSelected;
10 | const MenuPrinterContent({
11 | Key? key,
12 | required this.data,
13 | required this.isSelected,
14 | }) : super(key: key);
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | return Container(
19 | padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 10.0),
20 | decoration: BoxDecoration(
21 | border: Border.all(
22 | width: isSelected ? 4.0 : 1.0,
23 | color: isSelected ? AppColors.blueLight : AppColors.card),
24 | ),
25 | child: Column(
26 | crossAxisAlignment: CrossAxisAlignment.start,
27 | children: [
28 | Text(
29 | 'Name : ${data.name}',
30 | style: const TextStyle(
31 | fontWeight: FontWeight.w700,
32 | ),
33 | ),
34 | Text(
35 | 'macAddress: ${data.macAdress}',
36 | style: const TextStyle(
37 | fontSize: 12,
38 | ),
39 | ),
40 | ],
41 | ),
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at https://dart.dev/lints.
17 | #
18 | # Instead of disabling a lint rule for the entire project in the
19 | # section below, it can also be suppressed for a single line of code
20 | # or a specific dart file by using the `// ignore: name_of_lint` and
21 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
22 | # producing the lint.
23 | rules:
24 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
25 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
26 |
27 | # Additional information about this file can be found at
28 | # https://dart.dev/guides/language/analysis-options
29 |
--------------------------------------------------------------------------------
/lib/presentation/manage/pages/manage_menu_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/extensions/build_context_ext.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | import '../../../core/assets/assets.gen.dart';
5 | import '../../../core/components/menu_button.dart';
6 | import '../../../core/components/spaces.dart';
7 | import 'manage_printer_page.dart';
8 |
9 | class ManageMenuPage extends StatelessWidget {
10 | const ManageMenuPage({super.key});
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | return Scaffold(
15 | appBar: AppBar(
16 | title: const Text('Kelola'),
17 | centerTitle: true,
18 | ),
19 | body: Padding(
20 | padding: const EdgeInsets.all(32.0),
21 | child: Column(
22 | children: [
23 | Row(
24 | children: [
25 | MenuButton(
26 | iconPath: Assets.images.manageProduct.path,
27 | label: 'Kelola Produk',
28 | onPressed: () {},
29 | isImage: true,
30 | ),
31 | const SpaceWidth(15.0),
32 | MenuButton(
33 | iconPath: Assets.images.managePrinter.path,
34 | label: 'Kelola Printer',
35 | onPressed: () => context.push(const ManagePrinterPage()),
36 | isImage: true,
37 | ),
38 | ],
39 | ),
40 | ],
41 | ),
42 | ),
43 | );
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/lib/core/components/search_input.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../constants/colors.dart';
4 |
5 |
6 |
7 | class SearchInput extends StatelessWidget {
8 | final TextEditingController controller;
9 | final Function(String value)? onChanged;
10 | final VoidCallback? onTap;
11 |
12 | const SearchInput({
13 | super.key,
14 | required this.controller,
15 | this.onChanged,
16 | this.onTap,
17 | });
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | return Container(
22 | decoration: BoxDecoration(
23 | color: AppColors.white,
24 | borderRadius: BorderRadius.circular(8.0),
25 | ),
26 | child: TextFormField(
27 | onTap: onTap,
28 | readOnly: onTap != null,
29 | controller: controller,
30 | onChanged: onChanged,
31 | decoration: InputDecoration(
32 | hintText: 'Cari di sini',
33 | prefixIcon: const Icon(
34 | Icons.search,
35 | color: AppColors.primary,
36 | ),
37 | contentPadding: const EdgeInsets.all(16.0),
38 | border: OutlineInputBorder(
39 | borderRadius: BorderRadius.circular(8.0),
40 | borderSide: const BorderSide(color: Colors.grey),
41 | ),
42 | enabledBorder: OutlineInputBorder(
43 | borderRadius: BorderRadius.circular(8.0),
44 | borderSide: const BorderSide(color: Colors.grey),
45 | ),
46 | ),
47 | ),
48 | );
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '11.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | target 'RunnerTests' do
36 | inherit! :search_paths
37 | end
38 | end
39 |
40 | post_install do |installer|
41 | installer.pods_project.targets.each do |target|
42 | flutter_additional_ios_build_settings(target)
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/assets/icons/all_categories.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/lib/presentation/home/widgets/nav_item.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_svg/flutter_svg.dart';
3 |
4 | // import '../../../core/components/spaces.dart';
5 | import '../../../core/components/spaces.dart';
6 | import '../../../core/constants/colors.dart';
7 |
8 |
9 |
10 | class NavItem extends StatelessWidget {
11 | final String iconPath;
12 | final String label;
13 | final bool isActive;
14 | final VoidCallback onTap;
15 |
16 | const NavItem({
17 | super.key,
18 | required this.iconPath,
19 | required this.label,
20 | required this.isActive,
21 | required this.onTap,
22 | });
23 |
24 | @override
25 | Widget build(BuildContext context) {
26 | return InkWell(
27 | onTap: onTap,
28 | borderRadius: const BorderRadius.all(Radius.circular(16.0)),
29 | child: Column(
30 | mainAxisSize: MainAxisSize.min,
31 | children: [
32 | SizedBox(
33 | width: 25.0,
34 | height: 25.0,
35 | child: SvgPicture.asset(
36 | iconPath,
37 | colorFilter: ColorFilter.mode(
38 | isActive ? AppColors.black : AppColors.disabled,
39 | BlendMode.srcIn,
40 | ),
41 | ),
42 | ),
43 | const SpaceHeight(4.0),
44 | Text(
45 | label,
46 | style: TextStyle(
47 | fontSize: 12,
48 | color: isActive ? AppColors.black : AppColors.disabled,
49 | ),
50 | ),
51 | ],
52 | ),
53 | );
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/lib/presentation/manage/widgets/menu_printer_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/extensions/build_context_ext.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | import '../../../core/constants/colors.dart';
5 |
6 |
7 | class MenuPrinterButton extends StatelessWidget {
8 | final String label;
9 | final VoidCallback onPressed;
10 | final bool isActive;
11 |
12 | const MenuPrinterButton({
13 | super.key,
14 | required this.label,
15 | required this.onPressed,
16 | required this.isActive,
17 | });
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | return Flexible(
22 | child: InkWell(
23 | onTap: onPressed,
24 | child: Container(
25 | width: context.deviceWidth,
26 | padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
27 | decoration: BoxDecoration(
28 | color: isActive ? Colors.white : AppColors.card,
29 | borderRadius: BorderRadius.circular(6),
30 | boxShadow: isActive
31 | ? const [
32 | BoxShadow(
33 | color: AppColors.white,
34 | blurRadius: 2,
35 | offset: Offset(0, 1),
36 | spreadRadius: 0,
37 | ),
38 | ]
39 | : null,
40 | ),
41 | child: Text(
42 | label,
43 | textAlign: TextAlign.center,
44 | style: TextStyle(
45 | color: isActive ? AppColors.primary : AppColors.black,
46 | ),
47 | ),
48 | ),
49 | ),
50 | );
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/lib/core/components/custom_dropdown.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'spaces.dart';
4 |
5 | class CustomDropdown extends StatelessWidget {
6 | final String? value;
7 | final List items;
8 | final String label;
9 | final Function(String? value)? onChanged;
10 |
11 | const CustomDropdown({
12 | super.key,
13 | required this.value,
14 | required this.items,
15 | required this.label,
16 | this.onChanged,
17 | });
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | return Column(
22 | crossAxisAlignment: CrossAxisAlignment.start,
23 | children: [
24 | Text(
25 | label,
26 | style: const TextStyle(
27 | fontSize: 14,
28 | fontWeight: FontWeight.w700,
29 | ),
30 | ),
31 | const SpaceHeight(12.0),
32 | DropdownButtonFormField(
33 | value: value,
34 | onChanged: onChanged,
35 | items: items.map((String item) {
36 | return DropdownMenuItem(
37 | value: item,
38 | child: Text(item),
39 | );
40 | }).toList(),
41 | decoration: InputDecoration(
42 | border: OutlineInputBorder(
43 | borderRadius: BorderRadius.circular(16.0),
44 | borderSide: const BorderSide(color: Colors.grey),
45 | ),
46 | enabledBorder: OutlineInputBorder(
47 | borderRadius: BorderRadius.circular(16.0),
48 | borderSide: const BorderSide(color: Colors.grey),
49 | ),
50 | ),
51 | ),
52 | ],
53 | );
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/lib/presentation/order/widgets/process_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/extensions/int_ext.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | import '../../../core/components/spaces.dart';
5 | import '../../../core/constants/colors.dart';
6 |
7 | class ProcessButton extends StatelessWidget {
8 | final int price;
9 | final VoidCallback onPressed;
10 |
11 | const ProcessButton({
12 | super.key,
13 | required this.price,
14 | required this.onPressed,
15 | });
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return GestureDetector(
20 | onTap: onPressed,
21 | child: Container(
22 | padding: const EdgeInsets.all(20.0),
23 | decoration: const BoxDecoration(
24 | borderRadius: BorderRadius.all(Radius.circular(6.0)),
25 | color: AppColors.primary,
26 | ),
27 | child: Row(
28 | children: [
29 | Text(
30 | price.currencyFormatRp,
31 | style: const TextStyle(
32 | color: Colors.white,
33 | fontSize: 16,
34 | fontWeight: FontWeight.w700,
35 | ),
36 | ),
37 | const Spacer(),
38 | const Text(
39 | 'Proses',
40 | style: TextStyle(
41 | color: Colors.white,
42 | fontSize: 16,
43 | fontWeight: FontWeight.w700,
44 | ),
45 | ),
46 | const SpaceWidth(5.0),
47 | const Icon(
48 | Icons.chevron_right,
49 | color: AppColors.white,
50 | ),
51 | ],
52 | ),
53 | ),
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
14 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
29 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/assets/icons/qr_code.svg:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | Fic11 Starter Pos
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | fic11_starter_pos
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | CADisableMinimumFrameDurationOnPhone
45 |
46 | UIApplicationSupportsIndirectInputEvents
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: "db7ef5bf9f59442b0e200a90587e8fa5e0c6336a"
8 | channel: "stable"
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
17 | base_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
18 | - platform: android
19 | create_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
20 | base_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
21 | - platform: ios
22 | create_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
23 | base_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
24 | - platform: linux
25 | create_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
26 | base_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
27 | - platform: macos
28 | create_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
29 | base_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
30 | - platform: web
31 | create_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
32 | base_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
33 | - platform: windows
34 | create_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
35 | base_revision: db7ef5bf9f59442b0e200a90587e8fa5e0c6336a
36 |
37 | # User provided section
38 |
39 | # List of Local paths (relative to this file) that should be
40 | # ignored by the migrate tool.
41 | #
42 | # Files that are not part of the templates will be ignored by default.
43 | unmanaged_files:
44 | - 'lib/main.dart'
45 | - 'ios/Runner.xcodeproj/project.pbxproj'
46 |
--------------------------------------------------------------------------------
/lib/core/components/custom_text_field.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'spaces.dart';
4 |
5 | class CustomTextField extends StatelessWidget {
6 | final TextEditingController controller;
7 | final String label;
8 | final Function(String value)? onChanged;
9 | final bool obscureText;
10 | final TextInputType? keyboardType;
11 | final bool showLabel;
12 | final Widget? suffixIcon;
13 |
14 | const CustomTextField({
15 | super.key,
16 | required this.controller,
17 | required this.label,
18 | this.onChanged,
19 | this.obscureText = false,
20 | this.keyboardType,
21 | this.showLabel = true,
22 | this.suffixIcon,
23 | });
24 |
25 | @override
26 | Widget build(BuildContext context) {
27 | return Column(
28 | crossAxisAlignment: CrossAxisAlignment.start,
29 | children: [
30 | if (showLabel) ...[
31 | Text(
32 | label,
33 | style: const TextStyle(
34 | fontSize: 14,
35 | fontWeight: FontWeight.w700,
36 | ),
37 | ),
38 | const SpaceHeight(12.0),
39 | ],
40 | TextFormField(
41 | controller: controller,
42 | onChanged: onChanged,
43 | obscureText: obscureText,
44 | keyboardType: keyboardType,
45 | decoration: InputDecoration(
46 | suffixIcon: suffixIcon,
47 | border: OutlineInputBorder(
48 | borderRadius: BorderRadius.circular(16.0),
49 | borderSide: const BorderSide(color: Colors.grey),
50 | ),
51 | enabledBorder: OutlineInputBorder(
52 | borderRadius: BorderRadius.circular(16.0),
53 | borderSide: const BorderSide(color: Colors.grey),
54 | ),
55 | hintText: label,
56 | ),
57 | ),
58 | ],
59 | );
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/lib/core/components/tab_custom.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/extensions/build_context_ext.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | import '../constants/colors.dart';
5 |
6 |
7 |
8 | class TabCustom extends StatelessWidget {
9 | final List children;
10 | final EdgeInsetsGeometry? padding;
11 |
12 | const TabCustom({
13 | super.key,
14 | required this.children,
15 | this.padding,
16 | });
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | return Container(
21 | margin: padding,
22 | decoration: BoxDecoration(
23 | border: Border.all(color: AppColors.primary, width: 1.5),
24 | borderRadius: const BorderRadius.all(Radius.circular(9.0)),
25 | ),
26 | child: Row(
27 | children: children,
28 | ),
29 | );
30 | }
31 | }
32 |
33 | class TabMenu extends StatelessWidget {
34 | final String label;
35 | final VoidCallback onTap;
36 | final bool isActive;
37 |
38 | const TabMenu({
39 | super.key,
40 | required this.label,
41 | required this.onTap,
42 | this.isActive = false,
43 | });
44 |
45 | @override
46 | Widget build(BuildContext context) {
47 | return Flexible(
48 | child: InkWell(
49 | onTap: onTap,
50 | child: Container(
51 | width: context.deviceWidth,
52 | padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 15.0),
53 | decoration: BoxDecoration(
54 | borderRadius: const BorderRadius.all(Radius.circular(6.0)),
55 | color: isActive ? AppColors.primary : AppColors.white,
56 | ),
57 | child: Center(
58 | child: Text(
59 | label,
60 | style: TextStyle(
61 | color: isActive ? AppColors.white : AppColors.primary,
62 | fontSize: 16,
63 | fontWeight: FontWeight.w700,
64 | ),
65 | ),
66 | ),
67 | ),
68 | ),
69 | );
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | fic11_starter_pos
33 |
34 |
35 |
39 |
40 |
41 |
42 |
43 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/assets/icons/food.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.application"
3 | id "kotlin-android"
4 | id "dev.flutter.flutter-gradle-plugin"
5 | }
6 |
7 | def localProperties = new Properties()
8 | def localPropertiesFile = rootProject.file('local.properties')
9 | if (localPropertiesFile.exists()) {
10 | localPropertiesFile.withReader('UTF-8') { reader ->
11 | localProperties.load(reader)
12 | }
13 | }
14 |
15 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
16 | if (flutterVersionCode == null) {
17 | flutterVersionCode = '1'
18 | }
19 |
20 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
21 | if (flutterVersionName == null) {
22 | flutterVersionName = '1.0'
23 | }
24 |
25 | android {
26 | namespace "com.example.fic11_starter_pos"
27 | compileSdkVersion flutter.compileSdkVersion
28 | ndkVersion flutter.ndkVersion
29 |
30 | compileOptions {
31 | sourceCompatibility JavaVersion.VERSION_1_8
32 | targetCompatibility JavaVersion.VERSION_1_8
33 | }
34 |
35 | kotlinOptions {
36 | jvmTarget = '1.8'
37 | }
38 |
39 | sourceSets {
40 | main.java.srcDirs += 'src/main/kotlin'
41 | }
42 |
43 | defaultConfig {
44 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
45 | applicationId "com.example.fic11_starter_pos"
46 | // You can update the following values to match your application needs.
47 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
48 | minSdkVersion flutter.minSdkVersion
49 | targetSdkVersion flutter.targetSdkVersion
50 | versionCode flutterVersionCode.toInteger()
51 | versionName flutterVersionName
52 | }
53 |
54 | buildTypes {
55 | release {
56 | // TODO: Add your own signing config for the release build.
57 | // Signing with the debug keys for now, so `flutter run --release` works.
58 | signingConfig signingConfigs.debug
59 | }
60 | }
61 | }
62 |
63 | flutter {
64 | source '../..'
65 | }
66 |
67 | dependencies {}
68 |
--------------------------------------------------------------------------------
/lib/presentation/order/widgets/payment_qris_dialog.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/extensions/build_context_ext.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | import '../../../core/components/spaces.dart';
5 | import '../../../core/constants/colors.dart';
6 |
7 |
8 | class PaymentQrisDialog extends StatelessWidget {
9 | const PaymentQrisDialog({super.key});
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return AlertDialog(
14 | scrollable: true,
15 | contentPadding: const EdgeInsets.all(0),
16 | backgroundColor: AppColors.primary,
17 | content: Column(
18 | mainAxisSize: MainAxisSize.min,
19 | children: [
20 | const Padding(
21 | padding: EdgeInsets.all(12.0),
22 | child: Text(
23 | 'Pembayaran QRIS',
24 | style: TextStyle(
25 | color: Colors.white,
26 | fontSize: 16,
27 | fontFamily: 'Quicksand',
28 | fontWeight: FontWeight.w700,
29 | height: 0,
30 | ),
31 | ),
32 | ),
33 | const SpaceHeight(6.0),
34 | Container(
35 | width: context.deviceWidth,
36 | padding: const EdgeInsets.all(14.0),
37 | decoration: const BoxDecoration(
38 | borderRadius: BorderRadius.all(Radius.circular(20.0)),
39 | color: AppColors.white,
40 | ),
41 | child: const Column(
42 | mainAxisSize: MainAxisSize.min,
43 | children: [
44 | // SizedBox(
45 | // width: 256.0,
46 | // height: 256.0,
47 | // child: QrImageView(
48 | // data: 's.id/batch11',
49 | // version: QrVersions.auto,
50 | // ),
51 | // ),
52 | SpaceHeight(5.0),
53 | Text(
54 | 'Scan QRIS untuk melakukan pembayaran',
55 | textAlign: TextAlign.center,
56 | style: TextStyle(
57 | fontSize: 16,
58 | ),
59 | ),
60 | ],
61 | ),
62 | ),
63 | ],
64 | ),
65 | );
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/lib/core/components/menu_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/components/spaces.dart';
2 | import 'package:fic11_starter_pos/core/extensions/build_context_ext.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter_svg/flutter_svg.dart';
5 |
6 |
7 | import '../constants/colors.dart';
8 |
9 | class MenuButton extends StatelessWidget {
10 | final String iconPath;
11 | final String label;
12 | final bool isActive;
13 | final VoidCallback onPressed;
14 | final bool isImage;
15 | final double size;
16 |
17 | const MenuButton({
18 | super.key,
19 | required this.iconPath,
20 | required this.label,
21 | this.isActive = false,
22 | required this.onPressed,
23 | this.isImage = false,
24 | this.size = 90,
25 | });
26 |
27 | @override
28 | Widget build(BuildContext context) {
29 | return Flexible(
30 | child: InkWell(
31 | onTap: onPressed,
32 | borderRadius: const BorderRadius.all(Radius.circular(6.0)),
33 | child: Container(
34 | width: context.deviceWidth,
35 | padding: const EdgeInsets.all(8.0),
36 | decoration: BoxDecoration(
37 | color: isActive ? AppColors.primary : AppColors.white,
38 | borderRadius: const BorderRadius.all(Radius.circular(6.0)),
39 | boxShadow: [
40 | BoxShadow(
41 | offset: const Offset(0, 4),
42 | blurRadius: 20.0,
43 | blurStyle: BlurStyle.outer,
44 | spreadRadius: 0,
45 | color: AppColors.black.withOpacity(0.1),
46 | ),
47 | ],
48 | ),
49 | child: Column(
50 | children: [
51 | isImage
52 | ? Image.asset(iconPath,
53 | width: size, height: size, fit: BoxFit.contain)
54 | : SvgPicture.asset(
55 | iconPath,
56 | colorFilter: ColorFilter.mode(
57 | isActive ? AppColors.white : AppColors.primary,
58 | BlendMode.srcIn,
59 | ),
60 | ),
61 | const SpaceHeight(10.0),
62 | Text(
63 | label,
64 | style: TextStyle(
65 | color: isActive ? AppColors.white : AppColors.primary,
66 | fontSize: 12,
67 | fontWeight: FontWeight.w700,
68 | ),
69 | ),
70 | ],
71 | ),
72 | ),
73 | ),
74 | );
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/assets/icons/drink.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/lib/presentation/manage/widgets/change_price_bottom_sheet.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/extensions/build_context_ext.dart';
2 | import 'package:fic11_starter_pos/core/extensions/int_ext.dart';
3 | import 'package:fic11_starter_pos/core/extensions/string_ext.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | import '../../../core/assets/assets.gen.dart';
7 | import '../../../core/components/buttons.dart';
8 | import '../../../core/components/custom_text_field.dart';
9 | import '../../../core/components/spaces.dart';
10 | import '../../../core/constants/colors.dart';
11 |
12 | class ChangePriceBottomSheet extends StatelessWidget {
13 | final int price;
14 | const ChangePriceBottomSheet({super.key, required this.price});
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | final priceController = TextEditingController(text: price.currencyFormatRp);
19 |
20 | return Padding(
21 | padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 24.0),
22 | child: Column(
23 | crossAxisAlignment: CrossAxisAlignment.start,
24 | mainAxisSize: MainAxisSize.min,
25 | children: [
26 | const Text(
27 | 'Atur Harga',
28 | style: TextStyle(
29 | fontSize: 16,
30 | fontWeight: FontWeight.w700,
31 | ),
32 | ),
33 | const SizedBox(
34 | width: 90.0,
35 | child: Divider(color: AppColors.blueLight),
36 | ),
37 | const SpaceHeight(16.0),
38 | const Text(
39 | 'Masukkan Nominal',
40 | style: TextStyle(
41 | fontSize: 16,
42 | fontWeight: FontWeight.w400,
43 | ),
44 | ),
45 | const SpaceHeight(16.0),
46 | CustomTextField(
47 | controller: priceController,
48 | label: '',
49 | showLabel: false,
50 | keyboardType: TextInputType.number,
51 | onChanged: (value) {
52 | final int priceValue = value.toIntegerFromText;
53 | priceController.text = priceValue.currencyFormatRp;
54 | priceController.selection = TextSelection.fromPosition(
55 | TextPosition(offset: priceController.text.length));
56 | },
57 | suffixIcon: InkWell(
58 | onTap: () => priceController.clear(),
59 | child: Padding(
60 | padding: const EdgeInsets.all(12.0),
61 | child: Assets.icons.delete.svg(),
62 | ),
63 | ),
64 | ),
65 | const SpaceHeight(60.0),
66 | Button.filled(
67 | onPressed: () {
68 | context.pop();
69 | },
70 | label: 'Konfirmasi',
71 | ),
72 | ],
73 | ),
74 | );
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/lib/presentation/auth/pages/login_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/assets/assets.gen.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | import '../../../core/components/buttons.dart';
5 | import '../../../core/components/custom_text_field.dart';
6 | import '../../../core/components/spaces.dart';
7 | import '../../home/pages/dashboard_page.dart';
8 |
9 | class LoginPage extends StatefulWidget {
10 | const LoginPage({super.key});
11 |
12 | @override
13 | State createState() => _LoginPageState();
14 | }
15 |
16 | class _LoginPageState extends State {
17 | final usernameController = TextEditingController();
18 | final passwordController = TextEditingController();
19 |
20 | @override
21 | void dispose() {
22 | usernameController.dispose();
23 | passwordController.dispose();
24 | super.dispose();
25 | }
26 |
27 | @override
28 | Widget build(BuildContext context) {
29 | return Scaffold(
30 | body: ListView(
31 | padding: const EdgeInsets.all(16.0),
32 | children: [
33 | const SpaceHeight(80.0),
34 | Padding(
35 | padding: const EdgeInsets.symmetric(horizontal: 130.0),
36 | child: Image.asset(
37 | Assets.images.logo.path,
38 | width: 100,
39 | height: 100,
40 | )),
41 | const SpaceHeight(24.0),
42 | const Center(
43 | child: Text(
44 | "My Kedai",
45 | style: TextStyle(
46 | fontSize: 16,
47 | fontWeight: FontWeight.w700,
48 | color: Colors.black,
49 | ),
50 | ),
51 | ),
52 | const SpaceHeight(8.0),
53 | const Center(
54 | child: Text(
55 | "Masuk untuk kasir",
56 | style: TextStyle(
57 | fontSize: 12,
58 | fontWeight: FontWeight.w400,
59 | color: Colors.grey,
60 | ),
61 | ),
62 | ),
63 | const SpaceHeight(40.0),
64 | CustomTextField(
65 | controller: usernameController,
66 | label: 'Username',
67 | ),
68 | const SpaceHeight(12.0),
69 | CustomTextField(
70 | controller: passwordController,
71 | label: 'Password',
72 | obscureText: true,
73 | ),
74 | const SpaceHeight(24.0),
75 | Button.filled(
76 | onPressed: () {
77 | Navigator.pushReplacement(
78 | context,
79 | MaterialPageRoute(
80 | builder: (context) => const DashboardPage(),
81 | ),
82 | );
83 | },
84 | label: 'Masuk',
85 | ),
86 | ],
87 | ),
88 | );
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/lib/presentation/home/widgets/product_card.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 |
4 | import '../../../core/components/spaces.dart';
5 | import '../../../core/constants/colors.dart';
6 | import '../models/product_model.dart';
7 |
8 | class ProductCard extends StatelessWidget {
9 | final ProductModel data;
10 | final VoidCallback onCartButton;
11 |
12 | const ProductCard({
13 | super.key,
14 | required this.data,
15 | required this.onCartButton,
16 | });
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | return Container(
21 | padding: const EdgeInsets.all(16.0),
22 | decoration: ShapeDecoration(
23 | shape: RoundedRectangleBorder(
24 | side: const BorderSide(width: 1, color: AppColors.card),
25 | borderRadius: BorderRadius.circular(19),
26 | ),
27 | ),
28 | child: Column(
29 | crossAxisAlignment: CrossAxisAlignment.start,
30 | children: [
31 | Container(
32 | alignment: Alignment.center,
33 | padding: const EdgeInsets.all(12.0),
34 | decoration: BoxDecoration(
35 | shape: BoxShape.circle,
36 | color: AppColors.disabled.withOpacity(0.4),
37 | ),
38 | child: ClipRRect(
39 | borderRadius: const BorderRadius.all(Radius.circular(50.0)),
40 | child: Image.asset(
41 | data.image,
42 | width: 68,
43 | height: 68,
44 | fit: BoxFit.cover,
45 | ),
46 | ),
47 | ),
48 | const Spacer(),
49 | Text(
50 | data.name,
51 | style: const TextStyle(
52 | fontSize: 16,
53 | fontWeight: FontWeight.w700,
54 | ),
55 | maxLines: 2,
56 | overflow: TextOverflow.ellipsis,
57 | ),
58 | const SpaceHeight(8.0),
59 | Text(
60 | data.category.value,
61 | style: const TextStyle(
62 | color: AppColors.grey,
63 | fontSize: 12,
64 | ),
65 | ),
66 | const SpaceHeight(8.0),
67 | Row(
68 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
69 | children: [
70 | Flexible(
71 | child: Text(
72 | data.priceFormat,
73 | style: const TextStyle(
74 | fontWeight: FontWeight.w700,
75 | ),
76 | ),
77 | ),
78 | GestureDetector(
79 | onTap: onCartButton,
80 | child: Container(
81 | padding: const EdgeInsets.all(6),
82 | decoration: const BoxDecoration(
83 | borderRadius: BorderRadius.all(Radius.circular(9.0)),
84 | color: AppColors.primary,
85 | ),
86 | child: const Icon(
87 | Icons.add,
88 | color: Colors.white,
89 | ) //Assets.icons.orders.svg(),
90 | ),
91 | ),
92 | ],
93 | ),
94 | ],
95 | ),
96 | );
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/lib/core/components/image_picker_widget.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:image_picker/image_picker.dart';
5 |
6 | import '../assets/assets.gen.dart';
7 | import '../constants/colors.dart';
8 | import 'buttons.dart';
9 | import 'spaces.dart';
10 |
11 | class ImagePickerWidget extends StatefulWidget {
12 | final String label;
13 | final void Function(File? file) onChanged;
14 | final bool showLabel;
15 |
16 | const ImagePickerWidget({
17 | super.key,
18 | required this.label,
19 | required this.onChanged,
20 | this.showLabel = true,
21 | });
22 |
23 | @override
24 | State createState() => _ImagePickerWidgetState();
25 | }
26 |
27 | class _ImagePickerWidgetState extends State {
28 | String? imagePath;
29 |
30 | Future _pickImage() async {
31 | final pickedFile = await ImagePicker().pickImage(
32 | source: ImageSource.gallery,
33 | );
34 |
35 | setState(() {
36 | if (pickedFile != null) {
37 | imagePath = pickedFile.path;
38 | widget.onChanged(File(imagePath!));
39 | } else {
40 | debugPrint('No image selected.');
41 | widget.onChanged(null);
42 | }
43 | });
44 | }
45 |
46 | @override
47 | Widget build(BuildContext context) {
48 | return Column(
49 | crossAxisAlignment: CrossAxisAlignment.start,
50 | children: [
51 | if (widget.showLabel) ...[
52 | Text(
53 | widget.label,
54 | style: const TextStyle(
55 | fontSize: 14,
56 | fontWeight: FontWeight.w700,
57 | ),
58 | ),
59 | const SpaceHeight(12.0),
60 | ],
61 | Container(
62 | padding: const EdgeInsets.all(6.0),
63 | decoration: BoxDecoration(
64 | borderRadius: BorderRadius.circular(16.0),
65 | border: Border.all(color: AppColors.primary),
66 | ),
67 | child: Row(
68 | children: [
69 | SizedBox(
70 | width: 80.0,
71 | height: 80.0,
72 | child: ClipRRect(
73 | borderRadius: BorderRadius.circular(10.0),
74 | child: imagePath != null
75 | ? Image.file(
76 | File(imagePath!),
77 | fit: BoxFit.cover,
78 | )
79 | : Container(
80 | padding: const EdgeInsets.all(16.0),
81 | color: AppColors.black.withOpacity(0.05),
82 | child: Assets.icons.image.svg(),
83 | ),
84 | ),
85 | ),
86 | const Spacer(),
87 | Padding(
88 | padding: const EdgeInsets.only(right: 10.0),
89 | child: Button.filled(
90 | height: 30.0,
91 | width: 127.0,
92 | onPressed: _pickImage,
93 | label: 'Choose Photo',
94 | fontSize: 12.0,
95 | borderRadius: 5.0,
96 | ),
97 | ),
98 | ],
99 | ),
100 | ),
101 | ],
102 | );
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/lib/core/components/buttons.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../constants/colors.dart';
4 |
5 | enum ButtonStyle { filled, outlined }
6 |
7 | class Button extends StatelessWidget {
8 | const Button.filled({
9 | super.key,
10 | required this.onPressed,
11 | required this.label,
12 | this.style = ButtonStyle.filled,
13 | this.color = AppColors.primary,
14 | this.textColor = Colors.white,
15 | this.width = double.infinity,
16 | this.height = 50.0,
17 | this.borderRadius = 16.0,
18 | this.icon,
19 | this.disabled = false,
20 | this.fontSize = 16.0,
21 | });
22 |
23 | const Button.outlined({
24 | super.key,
25 | required this.onPressed,
26 | required this.label,
27 | this.style = ButtonStyle.outlined,
28 | this.color = AppColors.white,
29 | this.textColor = AppColors.primary,
30 | this.width = double.infinity,
31 | this.height = 50.0,
32 | this.borderRadius = 16.0,
33 | this.icon,
34 | this.disabled = false,
35 | this.fontSize = 16.0,
36 | });
37 |
38 | final Function() onPressed;
39 | final String label;
40 | final ButtonStyle style;
41 | final Color color;
42 | final Color textColor;
43 | final double width;
44 | final double height;
45 | final double borderRadius;
46 | final Widget? icon;
47 | final bool disabled;
48 | final double fontSize;
49 |
50 | @override
51 | Widget build(BuildContext context) {
52 | return SizedBox(
53 | height: height,
54 | width: width,
55 | child: style == ButtonStyle.filled
56 | ? ElevatedButton(
57 | onPressed: disabled ? null : onPressed,
58 | style: ElevatedButton.styleFrom(
59 | backgroundColor: color,
60 | shape: RoundedRectangleBorder(
61 | borderRadius: BorderRadius.circular(borderRadius),
62 | ),
63 | ),
64 | child: Row(
65 | mainAxisAlignment: MainAxisAlignment.center,
66 | children: [
67 | icon ?? const SizedBox.shrink(),
68 | if (icon != null) const SizedBox(width: 10.0),
69 | Text(
70 | label,
71 | style: TextStyle(
72 | color: textColor,
73 | fontSize: fontSize,
74 | fontWeight: FontWeight.w600,
75 | ),
76 | ),
77 | ],
78 | ),
79 | )
80 | : OutlinedButton(
81 | onPressed: disabled ? null : onPressed,
82 | style: OutlinedButton.styleFrom(
83 | backgroundColor: color,
84 | side: const BorderSide(color: Colors.grey),
85 | shape: RoundedRectangleBorder(
86 | borderRadius: BorderRadius.circular(borderRadius),
87 | ),
88 | ),
89 | child: Row(
90 | mainAxisAlignment: MainAxisAlignment.center,
91 | children: [
92 | icon ?? const SizedBox.shrink(),
93 | if (icon != null) const SizedBox(width: 10.0),
94 | Text(
95 | label,
96 | style: TextStyle(
97 | color: textColor,
98 | fontSize: fontSize,
99 | fontWeight: FontWeight.w600,
100 | ),
101 | ),
102 | ],
103 | ),
104 | ),
105 | );
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/lib/presentation/order/widgets/payment_cash_dialog.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/extensions/build_context_ext.dart';
2 | import 'package:fic11_starter_pos/core/extensions/int_ext.dart';
3 | import 'package:fic11_starter_pos/core/extensions/string_ext.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | import '../../../core/components/buttons.dart';
7 | import '../../../core/components/custom_text_field.dart';
8 | import '../../../core/components/spaces.dart';
9 | import '../../../core/constants/colors.dart';
10 | import 'payment_success_dialog.dart';
11 |
12 | class PaymentCashDialog extends StatelessWidget {
13 | final int price;
14 | const PaymentCashDialog({super.key, required this.price});
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | final priceController = TextEditingController(text: price.currencyFormatRp);
19 | return AlertDialog(
20 | scrollable: true,
21 | title: Stack(
22 | children: [
23 | IconButton(
24 | onPressed: () => context.pop(),
25 | icon: const Icon(Icons.highlight_off),
26 | color: AppColors.primary,
27 | ),
28 | const Center(
29 | child: Padding(
30 | padding: EdgeInsets.only(top: 12.0),
31 | child: Text(
32 | 'Pembayaran - Tunai',
33 | style: TextStyle(
34 | color: AppColors.primary,
35 | fontSize: 16,
36 | fontWeight: FontWeight.w700,
37 | ),
38 | ),
39 | ),
40 | ),
41 | ],
42 | ),
43 | content: Column(
44 | mainAxisSize: MainAxisSize.min,
45 | crossAxisAlignment: CrossAxisAlignment.start,
46 | children: [
47 | const SpaceHeight(16.0),
48 | CustomTextField(
49 | controller: priceController,
50 | label: '',
51 | showLabel: false,
52 | keyboardType: TextInputType.number,
53 | onChanged: (value) {
54 | final int priceValue = value.toIntegerFromText;
55 | priceController.text = priceValue.currencyFormatRp;
56 | priceController.selection = TextSelection.fromPosition(
57 | TextPosition(offset: priceController.text.length));
58 | },
59 | ),
60 | const SpaceHeight(16.0),
61 | Row(
62 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
63 | children: [
64 | Button.filled(
65 | onPressed: () {},
66 | label: 'Uang Pas',
67 | disabled: true,
68 | textColor: AppColors.primary,
69 | fontSize: 13.0,
70 | width: 112.0,
71 | height: 50.0,
72 | ),
73 | const SpaceWidth(4.0),
74 | Flexible(
75 | child: Button.filled(
76 | onPressed: () {},
77 | label: price.currencyFormatRp,
78 | disabled: true,
79 | textColor: AppColors.primary,
80 | fontSize: 13.0,
81 | height: 50.0,
82 | ),
83 | ),
84 | ],
85 | ),
86 | const SpaceHeight(30.0),
87 | Button.filled(
88 | onPressed: () {
89 | context.pop();
90 | showDialog(
91 | context: context,
92 | builder: (context) => const PaymentSuccessDialog(),
93 | );
94 | },
95 | label: 'Proses',
96 | ),
97 | ],
98 | ),
99 | );
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/lib/presentation/home/pages/dashboard_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/extensions/build_context_ext.dart';
2 | import 'package:fic11_starter_pos/presentation/home/pages/home_page.dart';
3 | import 'package:fic11_starter_pos/presentation/manage/pages/manage_menu_page.dart';
4 | import 'package:fic11_starter_pos/presentation/order/pages/orders_page.dart';
5 | import 'package:flutter/material.dart';
6 |
7 | import '../../../core/assets/assets.gen.dart';
8 | import '../../../core/constants/colors.dart';
9 | import '../widgets/nav_item.dart';
10 |
11 | class DashboardPage extends StatefulWidget {
12 | const DashboardPage({super.key});
13 |
14 | @override
15 | State createState() => _DashboardPageState();
16 | }
17 |
18 | class _DashboardPageState extends State {
19 | int _selectedIndex = 0;
20 |
21 | final List _pages = [
22 | const HomePage(),
23 | const OrdersPage(),
24 | const Placeholder(),
25 | const ManageMenuPage(),
26 | ];
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 | return Scaffold(
31 | body: _pages[_selectedIndex],
32 | bottomNavigationBar: Container(
33 | padding: const EdgeInsets.all(20.0),
34 | decoration: BoxDecoration(
35 | borderRadius: const BorderRadius.vertical(
36 | top: Radius.circular(30),
37 | ),
38 | color: AppColors.white,
39 | boxShadow: [
40 | BoxShadow(
41 | offset: const Offset(0, -2),
42 | blurRadius: 30.0,
43 | blurStyle: BlurStyle.outer,
44 | spreadRadius: 0,
45 | color: AppColors.black.withOpacity(0.08),
46 | ),
47 | ],
48 | ),
49 | child: Row(
50 | mainAxisAlignment: MainAxisAlignment.spaceAround,
51 | children: [
52 | NavItem(
53 | iconPath: Assets.icons.home.path,
54 | label: 'Home',
55 | isActive: _selectedIndex == 0,
56 | onTap: () => _onItemTapped(0),
57 | ),
58 | NavItem(
59 | iconPath: Assets.icons.orders.path,
60 | label: 'Orders',
61 | isActive: _selectedIndex == 1,
62 | onTap: () {
63 | // _onItemTapped(1);
64 | context.push(const OrdersPage());
65 | }),
66 | NavItem(
67 | iconPath: Assets.icons.payments.path,
68 | label: 'History',
69 | isActive: _selectedIndex == 2,
70 | onTap: () => _onItemTapped(2),
71 | ),
72 | NavItem(
73 | iconPath: Assets.icons.dashboard.path,
74 | label: 'Kelola',
75 | isActive: _selectedIndex == 3,
76 | onTap: () => _onItemTapped(3),
77 | ),
78 | ],
79 | ),
80 | ),
81 | // floatingActionButton: GestureDetector(
82 | // onTap: () => context.push(const AddProductpage()),
83 | // child: Container(
84 | // padding: const EdgeInsets.all(12.0),
85 | // decoration: const BoxDecoration(
86 | // shape: BoxShape.circle,
87 | // color: AppColors.primary,
88 | // ),
89 | // child: const Icon(
90 | // Icons.add,
91 | // color: AppColors.white,
92 | // size: 40.0,
93 | // ),
94 | // ),
95 | // ),
96 | // floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
97 | );
98 | }
99 |
100 | void _onItemTapped(int index) {
101 | setState(() {
102 | _selectedIndex = index;
103 | });
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: fic11_starter_pos
2 | description: "A new Flutter project."
3 | # The following line prevents the package from being accidentally published to
4 | # pub.dev using `flutter pub publish`. This is preferred for private packages.
5 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
6 |
7 | # The following defines the version and build number for your application.
8 | # A version number is three numbers separated by dots, like 1.2.43
9 | # followed by an optional build number separated by a +.
10 | # Both the version and the builder number may be overridden in flutter
11 | # build by specifying --build-name and --build-number, respectively.
12 | # In Android, build-name is used as versionName while build-number used as versionCode.
13 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
14 | # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
15 | # Read more about iOS versioning at
16 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
17 | # In Windows, build-name is used as the major, minor, and patch parts
18 | # of the product and file versions while build-number is used as the build suffix.
19 | version: 1.0.0+1
20 |
21 | environment:
22 | sdk: '>=3.2.0 <4.0.0'
23 |
24 | # Dependencies specify other packages that your package needs in order to work.
25 | # To automatically upgrade your package dependencies to the latest versions
26 | # consider running `flutter pub upgrade --major-versions`. Alternatively,
27 | # dependencies can be manually updated by changing the version numbers below to
28 | # the latest version available on pub.dev. To see which dependencies have newer
29 | # versions available, run `flutter pub outdated`.
30 | dependencies:
31 | cupertino_icons: ^1.0.2
32 | esc_pos_utils_plus: ^2.0.3
33 | flutter:
34 | sdk: flutter
35 | flutter_svg: ^2.0.9
36 | google_fonts: ^6.1.0
37 | image_picker: ^1.0.4
38 | intl: ^0.19.0
39 | print_bluetooth_thermal: ^1.0.9
40 |
41 | dev_dependencies:
42 | build_runner: ^2.4.6
43 | flutter_gen_runner: ^5.3.2
44 | flutter_lints: ^5.0.0
45 | flutter_test:
46 | sdk: flutter
47 |
48 | flutter_gen:
49 | output: lib/core/assets/
50 | integrations:
51 | flutter_svg: true
52 |
53 | # For information on the generic Dart part of this file, see the
54 | # following page: https://dart.dev/tools/pub/pubspec
55 | # The following section is specific to Flutter packages.
56 | flutter:
57 |
58 | # The following line ensures that the Material Icons font is
59 | # included with your application, so that you can use the icons in
60 | # the material Icons class.
61 | uses-material-design: true
62 | # To add assets to your application, add an assets section, like this:
63 | assets:
64 | - assets/images/
65 | - assets/icons/
66 | # An image asset can refer to one or more resolution-specific "variants", see
67 | # https://flutter.dev/assets-and-images/#resolution-aware
68 | # For details regarding adding assets from package dependencies, see
69 | # https://flutter.dev/assets-and-images/#from-packages
70 | # To add custom fonts to your application, add a fonts section here,
71 | # in this "flutter" section. Each entry in this list should have a
72 | # "family" key with the font family name, and a "fonts" key with a
73 | # list giving the asset and other descriptors for the font. For
74 | # example:
75 | # fonts:
76 | # - family: Schyler
77 | # fonts:
78 | # - asset: fonts/Schyler-Regular.ttf
79 | # - asset: fonts/Schyler-Italic.ttf
80 | # style: italic
81 | # - family: Trajan Pro
82 | # fonts:
83 | # - asset: fonts/TrajanPro.ttf
84 | # - asset: fonts/TrajanPro_Bold.ttf
85 | # weight: 700
86 | #
87 | # For details regarding fonts from package dependencies,
88 | # see https://flutter.dev/custom-fonts/#from-packages
89 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
43 |
49 |
50 |
51 |
52 |
53 |
63 |
65 |
71 |
72 |
73 |
74 |
80 |
82 |
88 |
89 |
90 |
91 |
93 |
94 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/lib/presentation/order/widgets/payment_success_dialog.dart:
--------------------------------------------------------------------------------
1 | import 'package:fic11_starter_pos/core/extensions/build_context_ext.dart';
2 | import 'package:fic11_starter_pos/core/extensions/date_time_ext.dart';
3 | import 'package:fic11_starter_pos/core/extensions/int_ext.dart';
4 | import 'package:fic11_starter_pos/presentation/home/pages/dashboard_page.dart';
5 | import 'package:fic11_starter_pos/presentation/manage/models/cwb_print.dart';
6 | import 'package:flutter/material.dart';
7 | import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
8 |
9 | import '../../../core/assets/assets.gen.dart';
10 | import '../../../core/components/buttons.dart';
11 | import '../../../core/components/spaces.dart';
12 |
13 | class PaymentSuccessDialog extends StatelessWidget {
14 | const PaymentSuccessDialog({super.key});
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | return AlertDialog(
19 | scrollable: true,
20 | title: Column(
21 | mainAxisSize: MainAxisSize.min,
22 | children: [
23 | Center(child: Assets.icons.done.svg()),
24 | const SpaceHeight(24.0),
25 | const Text(
26 | 'Pembayaran telah sukses dilakukan',
27 | textAlign: TextAlign.center,
28 | style: TextStyle(
29 | fontSize: 20,
30 | ),
31 | ),
32 | ],
33 | ),
34 | content: Column(
35 | mainAxisSize: MainAxisSize.min,
36 | crossAxisAlignment: CrossAxisAlignment.start,
37 | children: [
38 | const SpaceHeight(12.0),
39 | const _LabelValue(
40 | label: 'METODE PEMBAYARAN',
41 | value: 'Tunai',
42 | ),
43 | const Divider(height: 36.0),
44 | _LabelValue(
45 | label: 'TOTAL PEMBELIAN',
46 | value: 123000.currencyFormatRp,
47 | ),
48 | const Divider(height: 36.0),
49 | _LabelValue(
50 | label: 'NOMINAL BAYAR',
51 | value: 123000.currencyFormatRp,
52 | ),
53 | const Divider(height: 36.0),
54 | _LabelValue(
55 | label: 'WAKTU PEMBAYARAN',
56 | value: DateTime.now().toFormattedTime(),
57 | ),
58 | const SpaceHeight(40.0),
59 | Row(
60 | mainAxisSize: MainAxisSize.min,
61 | children: [
62 | Flexible(
63 | child: Button.filled(
64 | onPressed: () {
65 | context.pushReplacement(const DashboardPage());
66 | },
67 | label: 'Selesai',
68 | fontSize: 13,
69 | ),
70 | ),
71 | const SpaceWidth(10.0),
72 | Flexible(
73 | child: Button.outlined(
74 | onPressed: () async {
75 | final ticket = await CwbPrint.instance.bluetoothStart();
76 | final result =
77 | await PrintBluetoothThermal.writeBytes(ticket);
78 | },
79 | label: 'Print',
80 | icon: Assets.icons.print.svg(),
81 | fontSize: 13,
82 | ),
83 | ),
84 | ],
85 | ),
86 | ],
87 | ),
88 | );
89 | }
90 | }
91 |
92 | class _LabelValue extends StatelessWidget {
93 | final String label;
94 | final String value;
95 |
96 | const _LabelValue({
97 | required this.label,
98 | required this.value,
99 | });
100 |
101 | @override
102 | Widget build(BuildContext context) {
103 | return Column(
104 | crossAxisAlignment: CrossAxisAlignment.start,
105 | children: [
106 | Text(
107 | label,
108 | style: const TextStyle(),
109 | ),
110 | const SpaceHeight(5.0),
111 | Text(
112 | value,
113 | style: const TextStyle(
114 | fontWeight: FontWeight.w700,
115 | ),
116 | ),
117 | ],
118 | );
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/lib/presentation/order/pages/orders_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../../core/assets/assets.gen.dart';
4 | import '../../../core/components/menu_button.dart';
5 | import '../../../core/components/spaces.dart';
6 | import '../models/order_model.dart';
7 | import '../widgets/order_card.dart';
8 | import '../widgets/payment_cash_dialog.dart';
9 | import '../widgets/payment_qris_dialog.dart';
10 | import '../widgets/process_button.dart';
11 |
12 | class OrdersPage extends StatelessWidget {
13 | const OrdersPage({super.key});
14 |
15 | @override
16 | Widget build(BuildContext context) {
17 | final indexValue = ValueNotifier(0);
18 | const paddingHorizontal = EdgeInsets.symmetric(horizontal: 16.0);
19 | final List orders = [
20 | OrderModel(
21 | image: Assets.images.f1.path,
22 | name: 'Nutty Oat Latte',
23 | price: 39000,
24 | ),
25 | OrderModel(
26 | image: Assets.images.f2.path,
27 | name: 'Iced Latte',
28 | price: 24000,
29 | ),
30 | ];
31 |
32 | int calculateTotalPrice(List orders) {
33 | int totalPrice = 0;
34 | for (final order in orders) {
35 | totalPrice += order.price;
36 | }
37 | return totalPrice;
38 | }
39 |
40 | return Scaffold(
41 | appBar: AppBar(
42 | title: const Text('Order Detail'),
43 | centerTitle: true,
44 | actions: [
45 | IconButton(
46 | onPressed: () {},
47 | icon: Assets.icons.delete.svg(),
48 | ),
49 | ],
50 | ),
51 | body: StatefulBuilder(
52 | builder: (context, setState) => ListView.separated(
53 | padding: const EdgeInsets.symmetric(vertical: 16.0),
54 | itemCount: orders.length,
55 | separatorBuilder: (context, index) => const SpaceHeight(20.0),
56 | itemBuilder: (context, index) => OrderCard(
57 | padding: paddingHorizontal,
58 | data: orders[index],
59 | onDeleteTap: () {
60 | orders.removeAt(index);
61 | setState(() {});
62 | },
63 | ),
64 | ),
65 | ),
66 | bottomNavigationBar: Padding(
67 | padding: const EdgeInsets.all(8.0),
68 | child: Column(
69 | mainAxisSize: MainAxisSize.min,
70 | children: [
71 | ValueListenableBuilder(
72 | valueListenable: indexValue,
73 | builder: (context, value, _) => Row(
74 | children: [
75 | const SpaceWidth(10.0),
76 | MenuButton(
77 | iconPath: Assets.icons.cash.path,
78 | label: 'Tunai',
79 | isActive: value == 1,
80 | onPressed: () => indexValue.value = 1,
81 | ),
82 | const SpaceWidth(10.0),
83 | MenuButton(
84 | iconPath: Assets.icons.qrCode.path,
85 | label: 'QRIS',
86 | isActive: value == 2,
87 | onPressed: () => indexValue.value = 2,
88 | ),
89 | const SpaceWidth(10.0),
90 | ],
91 | ),
92 | ),
93 | const SpaceHeight(20.0),
94 | ProcessButton(
95 | price: 123000,
96 | onPressed: () async {
97 | if (indexValue.value == 0) {
98 | } else if (indexValue.value == 1) {
99 | showDialog(
100 | context: context,
101 | builder: (context) => PaymentCashDialog(
102 | price: calculateTotalPrice(orders),
103 | ),
104 | );
105 | } else if (indexValue.value == 2) {
106 | showDialog(
107 | context: context,
108 | barrierDismissible: false,
109 | builder: (context) => const PaymentQrisDialog(),
110 | );
111 | }
112 | },
113 | ),
114 | ],
115 | ),
116 | ),
117 | );
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/lib/presentation/order/widgets/order_card.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 |
4 | import '../../../core/components/spaces.dart';
5 | import '../../../core/constants/colors.dart';
6 | import '../models/order_model.dart';
7 |
8 | class OrderCard extends StatelessWidget {
9 | final OrderModel data;
10 | final VoidCallback onDeleteTap;
11 | final EdgeInsetsGeometry? padding;
12 |
13 | const OrderCard({
14 | super.key,
15 | required this.data,
16 | required this.onDeleteTap,
17 | this.padding,
18 | });
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return Stack(
23 | alignment: Alignment.bottomRight,
24 | children: [
25 | Container(
26 | margin: padding,
27 | padding: const EdgeInsets.all(16.0),
28 | decoration: ShapeDecoration(
29 | color: Colors.white,
30 | shape: RoundedRectangleBorder(
31 | side: const BorderSide(width: 2, color: Color(0xFFC7D0EB)),
32 | borderRadius: BorderRadius.circular(10),
33 | ),
34 | ),
35 | child: Row(
36 | children: [
37 | ClipRRect(
38 | borderRadius: const BorderRadius.all(Radius.circular(50.0)),
39 | child: Image.asset(
40 | data.image,
41 | width: 76,
42 | height: 76,
43 | fit: BoxFit.cover,
44 | ),
45 | ),
46 | const SpaceWidth(24.0),
47 | Flexible(
48 | child: Column(
49 | crossAxisAlignment: CrossAxisAlignment.start,
50 | children: [
51 | Row(
52 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
53 | children: [
54 | Text(
55 | data.name,
56 | style: const TextStyle(
57 | fontWeight: FontWeight.w700,
58 | ),
59 | ),
60 | Text(
61 | data.priceFormat,
62 | style: const TextStyle(
63 | fontWeight: FontWeight.w700,
64 | ),
65 | ),
66 | ],
67 | ),
68 | const SpaceHeight(20.0),
69 | StatefulBuilder(
70 | builder: (context, setState) => Row(
71 | children: [
72 | GestureDetector(
73 | onTap: () {
74 | if (data.quantity > 1) {
75 | data.quantity--;
76 | setState(() {});
77 | }
78 | },
79 | child: Container(
80 | color: AppColors.white,
81 | child: const Icon(
82 | Icons.remove_circle,
83 | color: AppColors.primary,
84 | ),
85 | ),
86 | ),
87 | SizedBox(
88 | width: 40.0,
89 | child: Center(
90 | child: Text(data.quantity.toString()),
91 | ),
92 | ),
93 | GestureDetector(
94 | onTap: () {
95 | data.quantity++;
96 | setState(() {});
97 | },
98 | child: Container(
99 | color: AppColors.white,
100 | child: const Icon(
101 | Icons.add_circle,
102 | color: AppColors.primary,
103 | ),
104 | ),
105 | ),
106 | ],
107 | ),
108 | ),
109 | ],
110 | ),
111 | ),
112 | ],
113 | ),
114 | ),
115 | Padding(
116 | padding: const EdgeInsets.only(right: 16.0),
117 | child: IconButton(
118 | onPressed: onDeleteTap,
119 | icon: const Icon(
120 | Icons.highlight_off,
121 | color: AppColors.primary,
122 | ),
123 | ),
124 | ),
125 | ],
126 | );
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/lib/presentation/manage/models/cwb_print.dart:
--------------------------------------------------------------------------------
1 | import 'package:esc_pos_utils_plus/esc_pos_utils_plus.dart';
2 |
3 | class CwbPrint {
4 | CwbPrint._init();
5 |
6 | static final CwbPrint instance = CwbPrint._init();
7 |
8 | Future> bluetoothStart() async {
9 | List bytes = [];
10 |
11 | final profile = await CapabilityProfile.load();
12 | final generator = Generator(PaperSize.mm58, profile);
13 |
14 | bytes += generator.reset();
15 | bytes += generator.text('My Kedai',
16 | styles: const PosStyles(
17 | bold: true,
18 | align: PosAlign.center,
19 | height: PosTextSize.size2,
20 | width: PosTextSize.size2,
21 | ));
22 | bytes += generator.text('is.mohidin',
23 | styles: const PosStyles(
24 | bold: true,
25 | align: PosAlign.center,
26 | height: PosTextSize.size1,
27 | width: PosTextSize.size1,
28 | ));
29 |
30 | bytes += generator.text('Link: s.id/batch11',
31 | styles: const PosStyles(bold: true, align: PosAlign.center));
32 | // bytes += generator.text(
33 | // 'Date : ${DateFormat('dd-MM-yyyy HH:mm').format(DateTime.now())}',
34 | // styles: const PosStyles(bold: false, align: PosAlign.center));
35 | bytes += generator.text('Start 12 Desember 2023',
36 | styles: const PosStyles(bold: false, align: PosAlign.center));
37 |
38 | bytes += generator.feed(1);
39 | bytes += generator.text('Pesanan:',
40 | styles: const PosStyles(bold: false, align: PosAlign.center));
41 |
42 | bytes += generator.text('Belajar Flutter',
43 | styles: const PosStyles(align: PosAlign.left));
44 |
45 | bytes += generator.row([
46 | PosColumn(
47 | text: 'Flutter Bloc',
48 | width: 8,
49 | styles: const PosStyles(align: PosAlign.left),
50 | ),
51 | PosColumn(
52 | text: 'Ya',
53 | width: 4,
54 | styles: const PosStyles(align: PosAlign.right),
55 | ),
56 | ]);
57 |
58 | bytes += generator.text('Belajar Laravel',
59 | styles: const PosStyles(align: PosAlign.left));
60 |
61 | bytes += generator.row([
62 | PosColumn(
63 | text: 'Laravel 10',
64 | width: 8,
65 | styles: const PosStyles(align: PosAlign.left),
66 | ),
67 | PosColumn(
68 | text: 'Ya',
69 | width: 4,
70 | styles: const PosStyles(align: PosAlign.right),
71 | ),
72 | ]);
73 | bytes += generator.text('Belajar DB',
74 | styles: const PosStyles(align: PosAlign.left));
75 |
76 | bytes += generator.row([
77 | PosColumn(
78 | text: 'MySQL',
79 | width: 8,
80 | styles: const PosStyles(align: PosAlign.left),
81 | ),
82 | PosColumn(
83 | text: 'Ya',
84 | width: 4,
85 | styles: const PosStyles(align: PosAlign.right),
86 | ),
87 | ]);
88 | bytes += generator.text('Belajar Server',
89 | styles: const PosStyles(align: PosAlign.left));
90 |
91 | bytes += generator.row([
92 | PosColumn(
93 | text: 'VPS, Cloud, Nginx',
94 | width: 8,
95 | styles: const PosStyles(align: PosAlign.left),
96 | ),
97 | PosColumn(
98 | text: 'Ya',
99 | width: 4,
100 | styles: const PosStyles(align: PosAlign.right),
101 | ),
102 | ]);
103 | bytes += generator.text('Komunitas',
104 | styles: const PosStyles(align: PosAlign.left));
105 |
106 | bytes += generator.row([
107 | PosColumn(
108 | text: 'Teman Ngoding',
109 | width: 8,
110 | styles: const PosStyles(align: PosAlign.left),
111 | ),
112 | PosColumn(
113 | text: 'Ya',
114 | width: 4,
115 | styles: const PosStyles(align: PosAlign.right),
116 | ),
117 | ]);
118 |
119 | bytes += generator.feed(1);
120 |
121 | bytes += generator.row([
122 | PosColumn(
123 | text: 'Total',
124 | width: 6,
125 | styles: const PosStyles(align: PosAlign.left),
126 | ),
127 | PosColumn(
128 | text: 'Rp 10 M',
129 | width: 6,
130 | styles: const PosStyles(align: PosAlign.right),
131 | ),
132 | ]);
133 |
134 | bytes += generator.row([
135 | PosColumn(
136 | text: 'Bayar',
137 | width: 6,
138 | styles: const PosStyles(align: PosAlign.left),
139 | ),
140 | PosColumn(
141 | text: 'Rp 10 M',
142 | width: 6,
143 | styles: const PosStyles(align: PosAlign.right),
144 | ),
145 | ]);
146 |
147 | bytes += generator.row([
148 | PosColumn(
149 | text: 'Pembayaran',
150 | width: 8,
151 | styles: const PosStyles(align: PosAlign.left),
152 | ),
153 | PosColumn(
154 | text: 'Transfer',
155 | width: 4,
156 | styles: const PosStyles(align: PosAlign.right),
157 | ),
158 | ]);
159 |
160 | bytes += generator.row([
161 | PosColumn(
162 | text: 'Mentor',
163 | width: 8,
164 | styles: const PosStyles(align: PosAlign.left),
165 | ),
166 | PosColumn(
167 | text: 'Ismail',
168 | width: 4,
169 | styles: const PosStyles(align: PosAlign.right),
170 | ),
171 | ]);
172 | bytes += generator.feed(1);
173 | bytes += generator.text('Check Link jagoflutter.com',
174 | styles: const PosStyles(bold: false, align: PosAlign.center));
175 | bytes += generator.feed(3);
176 |
177 | return bytes;
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/lib/presentation/home/pages/home_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../../core/assets/assets.gen.dart';
4 | import '../../../core/components/menu_button.dart';
5 | import '../../../core/components/search_input.dart';
6 | import '../../../core/components/spaces.dart';
7 | import '../models/product_category.dart';
8 | import '../models/product_model.dart';
9 | import '../widgets/product_card.dart';
10 | import '../widgets/product_empty.dart';
11 |
12 | class HomePage extends StatefulWidget {
13 | const HomePage({super.key});
14 |
15 | @override
16 | State createState() => _HomePageState();
17 | }
18 |
19 | class _HomePageState extends State {
20 | final searchController = TextEditingController();
21 | final indexValue = ValueNotifier(0);
22 |
23 | List searchResults = [];
24 | final List products = [
25 | ProductModel(
26 | image: Assets.images.f1.path,
27 | name: 'Nutty Latte',
28 | category: ProductCategory.drink,
29 | price: 39000,
30 | stock: 10,
31 | ),
32 | ProductModel(
33 | image: Assets.images.f2.path,
34 | name: 'Iced Latte',
35 | category: ProductCategory.drink,
36 | price: 24000,
37 | stock: 10,
38 | ),
39 | ProductModel(
40 | image: Assets.images.f3.path,
41 | name: 'Iced Mocha',
42 | category: ProductCategory.drink,
43 | price: 33000,
44 | stock: 10,
45 | ),
46 | ProductModel(
47 | image: Assets.images.f4.path,
48 | name: 'Hot Mocha',
49 | category: ProductCategory.drink,
50 | price: 33000,
51 | stock: 10,
52 | ),
53 | ];
54 |
55 | @override
56 | void initState() {
57 | searchResults = products;
58 | super.initState();
59 | }
60 |
61 | void onCategoryTap(int index) {
62 | searchController.clear();
63 | indexValue.value = index;
64 | if (index == 0) {
65 | searchResults = products;
66 | } else {
67 | searchResults = products
68 | .where((e) => e.category.index.toString().contains(index.toString()))
69 | .toList();
70 | }
71 | setState(() {});
72 | }
73 |
74 | @override
75 | Widget build(BuildContext context) {
76 | if (products.isEmpty) {
77 | return const ProductEmpty();
78 | }
79 | return SafeArea(
80 | child: Scaffold(
81 | appBar: AppBar(
82 | title: const Text(
83 | 'Menu',
84 | style: TextStyle(
85 | fontWeight: FontWeight.bold,
86 | ),
87 | ),
88 | centerTitle: true,
89 | ),
90 | body: ListView(
91 | padding: const EdgeInsets.all(16.0),
92 | children: [
93 | SearchInput(
94 | controller: searchController,
95 | onChanged: (value) {
96 | indexValue.value = 0;
97 | searchResults = products
98 | .where((e) =>
99 | e.name.toLowerCase().contains(value.toLowerCase()))
100 | .toList();
101 | setState(() {});
102 | },
103 | ),
104 | const SpaceHeight(20.0),
105 | ValueListenableBuilder(
106 | valueListenable: indexValue,
107 | builder: (context, value, _) => Row(
108 | children: [
109 | MenuButton(
110 | iconPath: Assets.icons.allCategories.path,
111 | label: 'Semua',
112 | isActive: value == 0,
113 | onPressed: () => onCategoryTap(0),
114 | ),
115 | const SpaceWidth(10.0),
116 | MenuButton(
117 | iconPath: Assets.icons.drink.path,
118 | label: 'Minuman',
119 | isActive: value == 1,
120 | onPressed: () => onCategoryTap(1),
121 | ),
122 | const SpaceWidth(10.0),
123 | MenuButton(
124 | iconPath: Assets.icons.food.path,
125 | label: 'Makanan',
126 | isActive: value == 2,
127 | onPressed: () => onCategoryTap(2),
128 | ),
129 | const SpaceWidth(10.0),
130 | MenuButton(
131 | iconPath: Assets.icons.snack.path,
132 | label: 'Snack',
133 | isActive: value == 3,
134 | onPressed: () => onCategoryTap(3),
135 | ),
136 | ],
137 | ),
138 | ),
139 | const SpaceHeight(35.0),
140 | if (searchResults.isEmpty)
141 | const Padding(
142 | padding: EdgeInsets.only(top: 80.0),
143 | child: ProductEmpty(),
144 | )
145 | else
146 | GridView.builder(
147 | shrinkWrap: true,
148 | physics: const NeverScrollableScrollPhysics(),
149 | itemCount: searchResults.length,
150 | gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
151 | childAspectRatio: 0.65,
152 | crossAxisCount: 2,
153 | crossAxisSpacing: 30.0,
154 | mainAxisSpacing: 30.0,
155 | ),
156 | itemBuilder: (context, index) => ProductCard(
157 | data: searchResults[index],
158 | onCartButton: () {},
159 | ),
160 | ),
161 | const SpaceHeight(30.0),
162 | ],
163 | ),
164 | ),
165 | );
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/lib/core/assets/assets.gen.dart:
--------------------------------------------------------------------------------
1 | /// GENERATED CODE - DO NOT MODIFY BY HAND
2 | /// *****************************************************
3 | /// FlutterGen
4 | /// *****************************************************
5 |
6 | // coverage:ignore-file
7 | // ignore_for_file: type=lint
8 | // ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use
9 |
10 | import 'package:flutter/widgets.dart';
11 | import 'package:flutter_svg/flutter_svg.dart';
12 | import 'package:flutter/services.dart';
13 |
14 | class $AssetsIconsGen {
15 | const $AssetsIconsGen();
16 |
17 | /// File path: assets/icons/all_categories.svg
18 | SvgGenImage get allCategories =>
19 | const SvgGenImage('assets/icons/all_categories.svg');
20 |
21 | /// File path: assets/icons/cash.svg
22 | SvgGenImage get cash => const SvgGenImage('assets/icons/cash.svg');
23 |
24 | /// File path: assets/icons/dashboard.svg
25 | SvgGenImage get dashboard => const SvgGenImage('assets/icons/dashboard.svg');
26 |
27 | /// File path: assets/icons/debit.svg
28 | SvgGenImage get debit => const SvgGenImage('assets/icons/debit.svg');
29 |
30 | /// File path: assets/icons/delete.svg
31 | SvgGenImage get delete => const SvgGenImage('assets/icons/delete.svg');
32 |
33 | /// File path: assets/icons/done.svg
34 | SvgGenImage get done => const SvgGenImage('assets/icons/done.svg');
35 |
36 | /// File path: assets/icons/drink.svg
37 | SvgGenImage get drink => const SvgGenImage('assets/icons/drink.svg');
38 |
39 | /// File path: assets/icons/food.svg
40 | SvgGenImage get food => const SvgGenImage('assets/icons/food.svg');
41 |
42 | /// File path: assets/icons/history.svg
43 | SvgGenImage get history => const SvgGenImage('assets/icons/history.svg');
44 |
45 | /// File path: assets/icons/home.svg
46 | SvgGenImage get home => const SvgGenImage('assets/icons/home.svg');
47 |
48 | /// File path: assets/icons/image.svg
49 | SvgGenImage get image => const SvgGenImage('assets/icons/image.svg');
50 |
51 | /// File path: assets/icons/orders.svg
52 | SvgGenImage get orders => const SvgGenImage('assets/icons/orders.svg');
53 |
54 | /// File path: assets/icons/payments.svg
55 | SvgGenImage get payments => const SvgGenImage('assets/icons/payments.svg');
56 |
57 | /// File path: assets/icons/print.svg
58 | SvgGenImage get print => const SvgGenImage('assets/icons/print.svg');
59 |
60 | /// File path: assets/icons/qr_code.svg
61 | SvgGenImage get qrCode => const SvgGenImage('assets/icons/qr_code.svg');
62 |
63 | /// File path: assets/icons/snack.svg
64 | SvgGenImage get snack => const SvgGenImage('assets/icons/snack.svg');
65 |
66 | /// List of all assets
67 | List get values => [
68 | allCategories,
69 | cash,
70 | dashboard,
71 | debit,
72 | delete,
73 | done,
74 | drink,
75 | food,
76 | history,
77 | home,
78 | image,
79 | orders,
80 | payments,
81 | print,
82 | qrCode,
83 | snack
84 | ];
85 | }
86 |
87 | class $AssetsImagesGen {
88 | const $AssetsImagesGen();
89 |
90 | /// File path: assets/images/f1.jpeg
91 | AssetGenImage get f1 => const AssetGenImage('assets/images/f1.jpeg');
92 |
93 | /// File path: assets/images/f2.jpeg
94 | AssetGenImage get f2 => const AssetGenImage('assets/images/f2.jpeg');
95 |
96 | /// File path: assets/images/f3.jpeg
97 | AssetGenImage get f3 => const AssetGenImage('assets/images/f3.jpeg');
98 |
99 | /// File path: assets/images/f4.jpeg
100 | AssetGenImage get f4 => const AssetGenImage('assets/images/f4.jpeg');
101 |
102 | /// File path: assets/images/f5.jpeg
103 | AssetGenImage get f5 => const AssetGenImage('assets/images/f5.jpeg');
104 |
105 | /// File path: assets/images/f6.jpeg
106 | AssetGenImage get f6 => const AssetGenImage('assets/images/f6.jpeg');
107 |
108 | /// File path: assets/images/f7.jpeg
109 | AssetGenImage get f7 => const AssetGenImage('assets/images/f7.jpeg');
110 |
111 | /// File path: assets/images/f8.jpeg
112 | AssetGenImage get f8 => const AssetGenImage('assets/images/f8.jpeg');
113 |
114 | /// File path: assets/images/logo.png
115 | AssetGenImage get logo => const AssetGenImage('assets/images/logo.png');
116 |
117 | /// File path: assets/images/manage_printer.png
118 | AssetGenImage get managePrinter =>
119 | const AssetGenImage('assets/images/manage_printer.png');
120 |
121 | /// File path: assets/images/manage_printerx.png
122 | AssetGenImage get managePrinterx =>
123 | const AssetGenImage('assets/images/manage_printerx.png');
124 |
125 | /// File path: assets/images/manage_product.png
126 | AssetGenImage get manageProduct =>
127 | const AssetGenImage('assets/images/manage_product.png');
128 |
129 | /// List of all assets
130 | List get values => [
131 | f1,
132 | f2,
133 | f3,
134 | f4,
135 | f5,
136 | f6,
137 | f7,
138 | f8,
139 | logo,
140 | managePrinter,
141 | managePrinterx,
142 | manageProduct
143 | ];
144 | }
145 |
146 | class Assets {
147 | Assets._();
148 |
149 | static const $AssetsIconsGen icons = $AssetsIconsGen();
150 | static const $AssetsImagesGen images = $AssetsImagesGen();
151 | }
152 |
153 | class AssetGenImage {
154 | const AssetGenImage(this._assetName);
155 |
156 | final String _assetName;
157 |
158 | Image image({
159 | Key? key,
160 | AssetBundle? bundle,
161 | ImageFrameBuilder? frameBuilder,
162 | ImageErrorWidgetBuilder? errorBuilder,
163 | String? semanticLabel,
164 | bool excludeFromSemantics = false,
165 | double? scale,
166 | double? width,
167 | double? height,
168 | Color? color,
169 | Animation? opacity,
170 | BlendMode? colorBlendMode,
171 | BoxFit? fit,
172 | AlignmentGeometry alignment = Alignment.center,
173 | ImageRepeat repeat = ImageRepeat.noRepeat,
174 | Rect? centerSlice,
175 | bool matchTextDirection = false,
176 | bool gaplessPlayback = false,
177 | bool isAntiAlias = false,
178 | String? package,
179 | FilterQuality filterQuality = FilterQuality.low,
180 | int? cacheWidth,
181 | int? cacheHeight,
182 | }) {
183 | return Image.asset(
184 | _assetName,
185 | key: key,
186 | bundle: bundle,
187 | frameBuilder: frameBuilder,
188 | errorBuilder: errorBuilder,
189 | semanticLabel: semanticLabel,
190 | excludeFromSemantics: excludeFromSemantics,
191 | scale: scale,
192 | width: width,
193 | height: height,
194 | color: color,
195 | opacity: opacity,
196 | colorBlendMode: colorBlendMode,
197 | fit: fit,
198 | alignment: alignment,
199 | repeat: repeat,
200 | centerSlice: centerSlice,
201 | matchTextDirection: matchTextDirection,
202 | gaplessPlayback: gaplessPlayback,
203 | isAntiAlias: isAntiAlias,
204 | package: package,
205 | filterQuality: filterQuality,
206 | cacheWidth: cacheWidth,
207 | cacheHeight: cacheHeight,
208 | );
209 | }
210 |
211 | ImageProvider provider({
212 | AssetBundle? bundle,
213 | String? package,
214 | }) {
215 | return AssetImage(
216 | _assetName,
217 | bundle: bundle,
218 | package: package,
219 | );
220 | }
221 |
222 | String get path => _assetName;
223 |
224 | String get keyName => _assetName;
225 | }
226 |
227 | class SvgGenImage {
228 | const SvgGenImage(this._assetName);
229 |
230 | final String _assetName;
231 |
232 | SvgPicture svg({
233 | Key? key,
234 | bool matchTextDirection = false,
235 | AssetBundle? bundle,
236 | String? package,
237 | double? width,
238 | double? height,
239 | BoxFit fit = BoxFit.contain,
240 | AlignmentGeometry alignment = Alignment.center,
241 | bool allowDrawingOutsideViewBox = false,
242 | WidgetBuilder? placeholderBuilder,
243 | String? semanticsLabel,
244 | bool excludeFromSemantics = false,
245 | SvgTheme theme = const SvgTheme(),
246 | ColorFilter? colorFilter,
247 | Clip clipBehavior = Clip.hardEdge,
248 | @deprecated Color? color,
249 | @deprecated BlendMode colorBlendMode = BlendMode.srcIn,
250 | @deprecated bool cacheColorFilter = false,
251 | }) {
252 | return SvgPicture.asset(
253 | _assetName,
254 | key: key,
255 | matchTextDirection: matchTextDirection,
256 | bundle: bundle,
257 | package: package,
258 | width: width,
259 | height: height,
260 | fit: fit,
261 | alignment: alignment,
262 | allowDrawingOutsideViewBox: allowDrawingOutsideViewBox,
263 | placeholderBuilder: placeholderBuilder,
264 | semanticsLabel: semanticsLabel,
265 | excludeFromSemantics: excludeFromSemantics,
266 | theme: theme,
267 | colorFilter: colorFilter,
268 | color: color,
269 | colorBlendMode: colorBlendMode,
270 | clipBehavior: clipBehavior,
271 | cacheColorFilter: cacheColorFilter,
272 | );
273 | }
274 |
275 | String get path => _assetName;
276 |
277 | String get keyName => _assetName;
278 | }
279 |
--------------------------------------------------------------------------------
/lib/presentation/manage/pages/manage_printer_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:esc_pos_utils_plus/esc_pos_utils_plus.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/services.dart';
4 | import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
5 |
6 | import 'package:fic11_starter_pos/core/extensions/build_context_ext.dart';
7 |
8 | import '../../../core/components/spaces.dart';
9 | import '../../../core/constants/colors.dart';
10 | import '../models/printer_model.dart';
11 | import '../widgets/menu_printer_button.dart';
12 | import '../widgets/menu_printer_content.dart';
13 |
14 | class ManagePrinterPage extends StatefulWidget {
15 | const ManagePrinterPage({super.key});
16 |
17 | @override
18 | State createState() => _ManagePrinterPageState();
19 | }
20 |
21 | class _ManagePrinterPageState extends State {
22 | int selectedIndex = 0;
23 | // final List datas = [
24 | // PrinterModel(
25 | // name: 'Galaxy A30',
26 | // address: 12324567412,
27 | // ),
28 | // PrinterModel(
29 | // name: 'Galaxy A30',
30 | // address: 12324567412,
31 | // ),
32 | // PrinterModel(
33 | // name: 'Galaxy A30',
34 | // address: 12324567412,
35 | // ),
36 | // ];
37 |
38 | String macName = '';
39 |
40 | String _info = "";
41 | String _msj = '';
42 | bool connected = false;
43 | List items = [];
44 | final List _options = [
45 | "permission bluetooth granted",
46 | "bluetooth enabled",
47 | "connection status",
48 | "update info"
49 | ];
50 |
51 | String _selectSize = "2";
52 | final _txtText = TextEditingController(text: "Hello developer");
53 | bool _progress = false;
54 | String _msjprogress = "";
55 |
56 | String optionprinttype = "58 mm";
57 | List options = ["58 mm", "80 mm"];
58 |
59 | @override
60 | void initState() {
61 | super.initState();
62 | initPlatformState();
63 | }
64 |
65 | Future initPlatformState() async {
66 | String platformVersion;
67 | int porcentbatery = 0;
68 | // Platform messages may fail, so we use a try/catch PlatformException.
69 | try {
70 | platformVersion = await PrintBluetoothThermal.platformVersion;
71 | print("patformversion: $platformVersion");
72 | porcentbatery = await PrintBluetoothThermal.batteryLevel;
73 | } on PlatformException {
74 | platformVersion = 'Failed to get platform version.';
75 | }
76 |
77 | // If the widget was removed from the tree while the asynchronous platform
78 | // message was in flight, we want to discard the reply rather than calling
79 | // setState to update our non-existent appearance.
80 | if (!mounted) return;
81 |
82 | final bool result = await PrintBluetoothThermal.bluetoothEnabled;
83 | print("bluetooth enabled: $result");
84 | if (result) {
85 | _msj = "Bluetooth enabled, please search and connect";
86 | } else {
87 | _msj = "Bluetooth not enabled";
88 | }
89 |
90 | setState(() {
91 | _info = "$platformVersion ($porcentbatery% battery)";
92 | });
93 | }
94 |
95 | Future getBluetoots() async {
96 | setState(() {
97 | _progress = true;
98 | _msjprogress = "Wait";
99 | items = [];
100 | });
101 | final List listResult =
102 | await PrintBluetoothThermal.pairedBluetooths;
103 |
104 | setState(() {
105 | _progress = false;
106 | });
107 |
108 | if (listResult.isEmpty) {
109 | _msj =
110 | "There are no bluetoohs linked, go to settings and link the printer";
111 | } else {
112 | _msj = "Touch an item in the list to connect";
113 | }
114 |
115 | setState(() {
116 | items = listResult;
117 | });
118 | }
119 |
120 | Future connect(String mac) async {
121 | setState(() {
122 | _progress = true;
123 | _msjprogress = "Connecting...";
124 | connected = false;
125 | });
126 | final bool result =
127 | await PrintBluetoothThermal.connect(macPrinterAddress: mac);
128 | print("state conected $result");
129 | if (result) connected = true;
130 | setState(() {
131 | _progress = false;
132 | });
133 | }
134 |
135 | Future disconnect() async {
136 | final bool status = await PrintBluetoothThermal.disconnect;
137 | setState(() {
138 | connected = false;
139 | });
140 | print("status disconnect $status");
141 | }
142 |
143 | Future printTest() async {
144 | bool conexionStatus = await PrintBluetoothThermal.connectionStatus;
145 | //print("connection status: $conexionStatus");
146 | if (conexionStatus) {
147 | List ticket = await testTicket();
148 | final result = await PrintBluetoothThermal.writeBytes(ticket);
149 | print("print test result: $result");
150 | } else {
151 | //no conectado, reconecte
152 | }
153 | }
154 |
155 | Future> testTicket() async {
156 | List bytes = [];
157 | // Using default profile
158 | final profile = await CapabilityProfile.load();
159 | final generator = Generator(
160 | optionprinttype == "58 mm" ? PaperSize.mm58 : PaperSize.mm80, profile);
161 | //bytes += generator.setGlobalFont(PosFontType.fontA);
162 | bytes += generator.reset();
163 |
164 | bytes +=
165 | generator.text('Code with Bahri', styles: const PosStyles(bold: true));
166 | bytes +=
167 | generator.text('Reverse text', styles: const PosStyles(reverse: true));
168 | bytes += generator.text('Underlined text',
169 | styles: const PosStyles(underline: true), linesAfter: 1);
170 | bytes += generator.text('Align left',
171 | styles: const PosStyles(align: PosAlign.left));
172 | bytes += generator.text('Align center',
173 | styles: const PosStyles(align: PosAlign.center));
174 | bytes += generator.text('Align right',
175 | styles: const PosStyles(align: PosAlign.right), linesAfter: 1);
176 |
177 | bytes += generator.text(
178 | 'FIC Batch 11',
179 | styles: const PosStyles(
180 | height: PosTextSize.size2,
181 | width: PosTextSize.size2,
182 | ),
183 | );
184 |
185 | bytes += generator.feed(2);
186 | //bytes += generator.cut();
187 | return bytes;
188 | }
189 |
190 | Future printWithoutPackage() async {
191 | //impresion sin paquete solo de PrintBluetoothTermal
192 | bool connectionStatus = await PrintBluetoothThermal.connectionStatus;
193 | if (connectionStatus) {
194 | String text = "${_txtText.text}\n";
195 | bool result = await PrintBluetoothThermal.writeString(
196 | printText: PrintTextSize(size: int.parse(_selectSize), text: text));
197 | print("status print result: $result");
198 | setState(() {
199 | _msj = "printed status: $result";
200 | });
201 | } else {
202 | //no conectado, reconecte
203 | setState(() {
204 | _msj = "no connected device";
205 | });
206 | print("no conectado");
207 | }
208 | }
209 |
210 | Future printString() async {
211 | bool conexionStatus = await PrintBluetoothThermal.connectionStatus;
212 | if (conexionStatus) {
213 | String enter = '\n';
214 | await PrintBluetoothThermal.writeBytes(enter.codeUnits);
215 | //size of 1-5
216 | String text = "Hello";
217 | await PrintBluetoothThermal.writeString(
218 | printText: PrintTextSize(size: 1, text: text));
219 | await PrintBluetoothThermal.writeString(
220 | printText: PrintTextSize(size: 2, text: "$text size 2"));
221 | await PrintBluetoothThermal.writeString(
222 | printText: PrintTextSize(size: 3, text: "$text size 3"));
223 | } else {
224 | //desconectado
225 | print("desconectado bluetooth $conexionStatus");
226 | }
227 | }
228 |
229 | @override
230 | Widget build(BuildContext context) {
231 | return Scaffold(
232 | appBar: AppBar(
233 | title: const Text('Kelola Printer'),
234 | centerTitle: true,
235 | ),
236 | body: ListView(
237 | padding: const EdgeInsets.all(24.0),
238 | children: [
239 | Container(
240 | width: context.deviceWidth / 2,
241 | padding: const EdgeInsets.all(8.0),
242 | decoration: BoxDecoration(
243 | color: AppColors.card,
244 | borderRadius: BorderRadius.circular(8),
245 | ),
246 | child: Row(
247 | mainAxisSize: MainAxisSize.min,
248 | children: [
249 | MenuPrinterButton(
250 | label: 'Search',
251 | onPressed: () {
252 | getBluetoots();
253 | selectedIndex = 0;
254 | setState(() {});
255 | },
256 | isActive: selectedIndex == 0,
257 | ),
258 | MenuPrinterButton(
259 | label: 'Disconnect',
260 | onPressed: () {
261 | selectedIndex = 1;
262 | setState(() {});
263 | },
264 | isActive: selectedIndex == 1,
265 | ),
266 | MenuPrinterButton(
267 | label: 'Test',
268 | onPressed: () {
269 | selectedIndex = 2;
270 | setState(() {});
271 | },
272 | isActive: selectedIndex == 2,
273 | ),
274 | ],
275 | ),
276 | ),
277 | const SpaceHeight(34.0),
278 | _Body(
279 | // selectedIndex: selectedIndex,
280 | macName: macName,
281 | datas: items,
282 | clickHandler: (mac) async {
283 | macName = mac;
284 | await connect(mac);
285 | setState(() {});
286 | },
287 | ),
288 | ],
289 | ),
290 | );
291 | }
292 | }
293 |
294 | class _Body extends StatelessWidget {
295 | // final int selectedIndex;
296 | final String macName;
297 | final List datas;
298 |
299 | //clickHandler
300 | final Function(String) clickHandler;
301 |
302 | const _Body({
303 | Key? key,
304 | required this.macName,
305 | required this.datas,
306 | required this.clickHandler,
307 | }) : super(key: key);
308 |
309 | @override
310 | Widget build(BuildContext context) {
311 | if (datas.isEmpty) {
312 | return const Text('No data available');
313 | } else {
314 | return Container(
315 | padding: const EdgeInsets.all(24.0),
316 | decoration: BoxDecoration(
317 | color: Colors.white,
318 | border: Border.all(color: AppColors.card, width: 2),
319 | borderRadius: BorderRadius.circular(6),
320 | ),
321 | child: ListView.separated(
322 | shrinkWrap: true,
323 | physics: const NeverScrollableScrollPhysics(),
324 | itemCount: datas.length,
325 | separatorBuilder: (context, index) => const SpaceHeight(16.0),
326 | itemBuilder: (context, index) => InkWell(
327 | onTap: () {
328 | clickHandler(datas[index].macAdress);
329 | },
330 | child: MenuPrinterContent(
331 | isSelected: macName == datas[index].macAdress,
332 | data: datas[index],
333 | ),
334 | ),
335 | ),
336 | );
337 | }
338 | // return const Placeholder();
339 | }
340 | }
341 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 54;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
16 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXContainerItemProxy section */
20 | 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
21 | isa = PBXContainerItemProxy;
22 | containerPortal = 97C146E61CF9000F007C117D /* Project object */;
23 | proxyType = 1;
24 | remoteGlobalIDString = 97C146ED1CF9000F007C117D;
25 | remoteInfo = Runner;
26 | };
27 | /* End PBXContainerItemProxy section */
28 |
29 | /* Begin PBXCopyFilesBuildPhase section */
30 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
31 | isa = PBXCopyFilesBuildPhase;
32 | buildActionMask = 2147483647;
33 | dstPath = "";
34 | dstSubfolderSpec = 10;
35 | files = (
36 | );
37 | name = "Embed Frameworks";
38 | runOnlyForDeploymentPostprocessing = 0;
39 | };
40 | /* End PBXCopyFilesBuildPhase section */
41 |
42 | /* Begin PBXFileReference section */
43 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
44 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
45 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
46 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
47 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
48 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
49 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
50 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
51 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
52 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
53 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
54 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
55 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
56 | 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
57 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
58 | /* End PBXFileReference section */
59 |
60 | /* Begin PBXFrameworksBuildPhase section */
61 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
62 | isa = PBXFrameworksBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | );
66 | runOnlyForDeploymentPostprocessing = 0;
67 | };
68 | /* End PBXFrameworksBuildPhase section */
69 |
70 | /* Begin PBXGroup section */
71 | 9740EEB11CF90186004384FC /* Flutter */ = {
72 | isa = PBXGroup;
73 | children = (
74 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
75 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
76 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
77 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
78 | );
79 | name = Flutter;
80 | sourceTree = "";
81 | };
82 | 331C8082294A63A400263BE5 /* RunnerTests */ = {
83 | isa = PBXGroup;
84 | children = (
85 | 331C807B294A618700263BE5 /* RunnerTests.swift */,
86 | );
87 | path = RunnerTests;
88 | sourceTree = "";
89 | };
90 | 97C146E51CF9000F007C117D = {
91 | isa = PBXGroup;
92 | children = (
93 | 9740EEB11CF90186004384FC /* Flutter */,
94 | 97C146F01CF9000F007C117D /* Runner */,
95 | 97C146EF1CF9000F007C117D /* Products */,
96 | 331C8082294A63A400263BE5 /* RunnerTests */,
97 | );
98 | sourceTree = "";
99 | };
100 | 97C146EF1CF9000F007C117D /* Products */ = {
101 | isa = PBXGroup;
102 | children = (
103 | 97C146EE1CF9000F007C117D /* Runner.app */,
104 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */,
105 | );
106 | name = Products;
107 | sourceTree = "";
108 | };
109 | 97C146F01CF9000F007C117D /* Runner */ = {
110 | isa = PBXGroup;
111 | children = (
112 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
113 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
114 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
115 | 97C147021CF9000F007C117D /* Info.plist */,
116 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
117 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
118 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
119 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
120 | );
121 | path = Runner;
122 | sourceTree = "";
123 | };
124 | /* End PBXGroup section */
125 |
126 | /* Begin PBXNativeTarget section */
127 | 331C8080294A63A400263BE5 /* RunnerTests */ = {
128 | isa = PBXNativeTarget;
129 | buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
130 | buildPhases = (
131 | 331C807D294A63A400263BE5 /* Sources */,
132 | 331C807E294A63A400263BE5 /* Frameworks */,
133 | 331C807F294A63A400263BE5 /* Resources */,
134 | );
135 | buildRules = (
136 | );
137 | dependencies = (
138 | 331C8086294A63A400263BE5 /* PBXTargetDependency */,
139 | );
140 | name = RunnerTests;
141 | productName = RunnerTests;
142 | productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
143 | productType = "com.apple.product-type.bundle.unit-test";
144 | };
145 | 97C146ED1CF9000F007C117D /* Runner */ = {
146 | isa = PBXNativeTarget;
147 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
148 | buildPhases = (
149 | 9740EEB61CF901F6004384FC /* Run Script */,
150 | 97C146EA1CF9000F007C117D /* Sources */,
151 | 97C146EB1CF9000F007C117D /* Frameworks */,
152 | 97C146EC1CF9000F007C117D /* Resources */,
153 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
154 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
155 | );
156 | buildRules = (
157 | );
158 | dependencies = (
159 | );
160 | name = Runner;
161 | productName = Runner;
162 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
163 | productType = "com.apple.product-type.application";
164 | };
165 | /* End PBXNativeTarget section */
166 |
167 | /* Begin PBXProject section */
168 | 97C146E61CF9000F007C117D /* Project object */ = {
169 | isa = PBXProject;
170 | attributes = {
171 | BuildIndependentTargetsInParallel = YES;
172 | LastUpgradeCheck = 1430;
173 | ORGANIZATIONNAME = "";
174 | TargetAttributes = {
175 | 331C8080294A63A400263BE5 = {
176 | CreatedOnToolsVersion = 14.0;
177 | TestTargetID = 97C146ED1CF9000F007C117D;
178 | };
179 | 97C146ED1CF9000F007C117D = {
180 | CreatedOnToolsVersion = 7.3.1;
181 | LastSwiftMigration = 1100;
182 | };
183 | };
184 | };
185 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
186 | compatibilityVersion = "Xcode 9.3";
187 | developmentRegion = en;
188 | hasScannedForEncodings = 0;
189 | knownRegions = (
190 | en,
191 | Base,
192 | );
193 | mainGroup = 97C146E51CF9000F007C117D;
194 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
195 | projectDirPath = "";
196 | projectRoot = "";
197 | targets = (
198 | 97C146ED1CF9000F007C117D /* Runner */,
199 | 331C8080294A63A400263BE5 /* RunnerTests */,
200 | );
201 | };
202 | /* End PBXProject section */
203 |
204 | /* Begin PBXResourcesBuildPhase section */
205 | 331C807F294A63A400263BE5 /* Resources */ = {
206 | isa = PBXResourcesBuildPhase;
207 | buildActionMask = 2147483647;
208 | files = (
209 | );
210 | runOnlyForDeploymentPostprocessing = 0;
211 | };
212 | 97C146EC1CF9000F007C117D /* Resources */ = {
213 | isa = PBXResourcesBuildPhase;
214 | buildActionMask = 2147483647;
215 | files = (
216 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
217 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
218 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
219 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
220 | );
221 | runOnlyForDeploymentPostprocessing = 0;
222 | };
223 | /* End PBXResourcesBuildPhase section */
224 |
225 | /* Begin PBXShellScriptBuildPhase section */
226 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
227 | isa = PBXShellScriptBuildPhase;
228 | alwaysOutOfDate = 1;
229 | buildActionMask = 2147483647;
230 | files = (
231 | );
232 | inputPaths = (
233 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
234 | );
235 | name = "Thin Binary";
236 | outputPaths = (
237 | );
238 | runOnlyForDeploymentPostprocessing = 0;
239 | shellPath = /bin/sh;
240 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
241 | };
242 | 9740EEB61CF901F6004384FC /* Run Script */ = {
243 | isa = PBXShellScriptBuildPhase;
244 | alwaysOutOfDate = 1;
245 | buildActionMask = 2147483647;
246 | files = (
247 | );
248 | inputPaths = (
249 | );
250 | name = "Run Script";
251 | outputPaths = (
252 | );
253 | runOnlyForDeploymentPostprocessing = 0;
254 | shellPath = /bin/sh;
255 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
256 | };
257 | /* End PBXShellScriptBuildPhase section */
258 |
259 | /* Begin PBXSourcesBuildPhase section */
260 | 331C807D294A63A400263BE5 /* Sources */ = {
261 | isa = PBXSourcesBuildPhase;
262 | buildActionMask = 2147483647;
263 | files = (
264 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
265 | );
266 | runOnlyForDeploymentPostprocessing = 0;
267 | };
268 | 97C146EA1CF9000F007C117D /* Sources */ = {
269 | isa = PBXSourcesBuildPhase;
270 | buildActionMask = 2147483647;
271 | files = (
272 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
273 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
274 | );
275 | runOnlyForDeploymentPostprocessing = 0;
276 | };
277 | /* End PBXSourcesBuildPhase section */
278 |
279 | /* Begin PBXTargetDependency section */
280 | 331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
281 | isa = PBXTargetDependency;
282 | target = 97C146ED1CF9000F007C117D /* Runner */;
283 | targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
284 | };
285 | /* End PBXTargetDependency section */
286 |
287 | /* Begin PBXVariantGroup section */
288 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
289 | isa = PBXVariantGroup;
290 | children = (
291 | 97C146FB1CF9000F007C117D /* Base */,
292 | );
293 | name = Main.storyboard;
294 | sourceTree = "";
295 | };
296 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
297 | isa = PBXVariantGroup;
298 | children = (
299 | 97C147001CF9000F007C117D /* Base */,
300 | );
301 | name = LaunchScreen.storyboard;
302 | sourceTree = "";
303 | };
304 | /* End PBXVariantGroup section */
305 |
306 | /* Begin XCBuildConfiguration section */
307 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
308 | isa = XCBuildConfiguration;
309 | buildSettings = {
310 | ALWAYS_SEARCH_USER_PATHS = NO;
311 | CLANG_ANALYZER_NONNULL = YES;
312 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
313 | CLANG_CXX_LIBRARY = "libc++";
314 | CLANG_ENABLE_MODULES = YES;
315 | CLANG_ENABLE_OBJC_ARC = YES;
316 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
317 | CLANG_WARN_BOOL_CONVERSION = YES;
318 | CLANG_WARN_COMMA = YES;
319 | CLANG_WARN_CONSTANT_CONVERSION = YES;
320 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
321 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
322 | CLANG_WARN_EMPTY_BODY = YES;
323 | CLANG_WARN_ENUM_CONVERSION = YES;
324 | CLANG_WARN_INFINITE_RECURSION = YES;
325 | CLANG_WARN_INT_CONVERSION = YES;
326 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
327 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
328 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
329 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
330 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
331 | CLANG_WARN_STRICT_PROTOTYPES = YES;
332 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
333 | CLANG_WARN_UNREACHABLE_CODE = YES;
334 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
336 | COPY_PHASE_STRIP = NO;
337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
338 | ENABLE_NS_ASSERTIONS = NO;
339 | ENABLE_STRICT_OBJC_MSGSEND = YES;
340 | GCC_C_LANGUAGE_STANDARD = gnu99;
341 | GCC_NO_COMMON_BLOCKS = YES;
342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
344 | GCC_WARN_UNDECLARED_SELECTOR = YES;
345 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
346 | GCC_WARN_UNUSED_FUNCTION = YES;
347 | GCC_WARN_UNUSED_VARIABLE = YES;
348 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
349 | MTL_ENABLE_DEBUG_INFO = NO;
350 | SDKROOT = iphoneos;
351 | SUPPORTED_PLATFORMS = iphoneos;
352 | TARGETED_DEVICE_FAMILY = "1,2";
353 | VALIDATE_PRODUCT = YES;
354 | };
355 | name = Profile;
356 | };
357 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
358 | isa = XCBuildConfiguration;
359 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
360 | buildSettings = {
361 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
362 | CLANG_ENABLE_MODULES = YES;
363 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
364 | ENABLE_BITCODE = NO;
365 | INFOPLIST_FILE = Runner/Info.plist;
366 | LD_RUNPATH_SEARCH_PATHS = (
367 | "$(inherited)",
368 | "@executable_path/Frameworks",
369 | );
370 | PRODUCT_BUNDLE_IDENTIFIER = com.example.fic11StarterPos;
371 | PRODUCT_NAME = "$(TARGET_NAME)";
372 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
373 | SWIFT_VERSION = 5.0;
374 | VERSIONING_SYSTEM = "apple-generic";
375 | };
376 | name = Profile;
377 | };
378 | 331C8088294A63A400263BE5 /* Debug */ = {
379 | isa = XCBuildConfiguration;
380 | baseConfigurationReference = AE0B7B92F70575B8D7E0D07E /* Pods-RunnerTests.debug.xcconfig */;
381 | buildSettings = {
382 | BUNDLE_LOADER = "$(TEST_HOST)";
383 | CODE_SIGN_STYLE = Automatic;
384 | CURRENT_PROJECT_VERSION = 1;
385 | GENERATE_INFOPLIST_FILE = YES;
386 | MARKETING_VERSION = 1.0;
387 | PRODUCT_BUNDLE_IDENTIFIER = com.example.fic11StarterPos.RunnerTests;
388 | PRODUCT_NAME = "$(TARGET_NAME)";
389 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
390 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
391 | SWIFT_VERSION = 5.0;
392 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
393 | };
394 | name = Debug;
395 | };
396 | 331C8089294A63A400263BE5 /* Release */ = {
397 | isa = XCBuildConfiguration;
398 | baseConfigurationReference = 89B67EB44CE7B6631473024E /* Pods-RunnerTests.release.xcconfig */;
399 | buildSettings = {
400 | BUNDLE_LOADER = "$(TEST_HOST)";
401 | CODE_SIGN_STYLE = Automatic;
402 | CURRENT_PROJECT_VERSION = 1;
403 | GENERATE_INFOPLIST_FILE = YES;
404 | MARKETING_VERSION = 1.0;
405 | PRODUCT_BUNDLE_IDENTIFIER = com.example.fic11StarterPos.RunnerTests;
406 | PRODUCT_NAME = "$(TARGET_NAME)";
407 | SWIFT_VERSION = 5.0;
408 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
409 | };
410 | name = Release;
411 | };
412 | 331C808A294A63A400263BE5 /* Profile */ = {
413 | isa = XCBuildConfiguration;
414 | baseConfigurationReference = 640959BDD8F10B91D80A66BE /* Pods-RunnerTests.profile.xcconfig */;
415 | buildSettings = {
416 | BUNDLE_LOADER = "$(TEST_HOST)";
417 | CODE_SIGN_STYLE = Automatic;
418 | CURRENT_PROJECT_VERSION = 1;
419 | GENERATE_INFOPLIST_FILE = YES;
420 | MARKETING_VERSION = 1.0;
421 | PRODUCT_BUNDLE_IDENTIFIER = com.example.fic11StarterPos.RunnerTests;
422 | PRODUCT_NAME = "$(TARGET_NAME)";
423 | SWIFT_VERSION = 5.0;
424 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
425 | };
426 | name = Profile;
427 | };
428 | 97C147031CF9000F007C117D /* Debug */ = {
429 | isa = XCBuildConfiguration;
430 | buildSettings = {
431 | ALWAYS_SEARCH_USER_PATHS = NO;
432 | CLANG_ANALYZER_NONNULL = YES;
433 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
434 | CLANG_CXX_LIBRARY = "libc++";
435 | CLANG_ENABLE_MODULES = YES;
436 | CLANG_ENABLE_OBJC_ARC = YES;
437 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
438 | CLANG_WARN_BOOL_CONVERSION = YES;
439 | CLANG_WARN_COMMA = YES;
440 | CLANG_WARN_CONSTANT_CONVERSION = YES;
441 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
442 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
443 | CLANG_WARN_EMPTY_BODY = YES;
444 | CLANG_WARN_ENUM_CONVERSION = YES;
445 | CLANG_WARN_INFINITE_RECURSION = YES;
446 | CLANG_WARN_INT_CONVERSION = YES;
447 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
448 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
449 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
450 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
451 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
452 | CLANG_WARN_STRICT_PROTOTYPES = YES;
453 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
454 | CLANG_WARN_UNREACHABLE_CODE = YES;
455 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
456 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
457 | COPY_PHASE_STRIP = NO;
458 | DEBUG_INFORMATION_FORMAT = dwarf;
459 | ENABLE_STRICT_OBJC_MSGSEND = YES;
460 | ENABLE_TESTABILITY = YES;
461 | GCC_C_LANGUAGE_STANDARD = gnu99;
462 | GCC_DYNAMIC_NO_PIC = NO;
463 | GCC_NO_COMMON_BLOCKS = YES;
464 | GCC_OPTIMIZATION_LEVEL = 0;
465 | GCC_PREPROCESSOR_DEFINITIONS = (
466 | "DEBUG=1",
467 | "$(inherited)",
468 | );
469 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
470 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
471 | GCC_WARN_UNDECLARED_SELECTOR = YES;
472 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
473 | GCC_WARN_UNUSED_FUNCTION = YES;
474 | GCC_WARN_UNUSED_VARIABLE = YES;
475 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
476 | MTL_ENABLE_DEBUG_INFO = YES;
477 | ONLY_ACTIVE_ARCH = YES;
478 | SDKROOT = iphoneos;
479 | TARGETED_DEVICE_FAMILY = "1,2";
480 | };
481 | name = Debug;
482 | };
483 | 97C147041CF9000F007C117D /* Release */ = {
484 | isa = XCBuildConfiguration;
485 | buildSettings = {
486 | ALWAYS_SEARCH_USER_PATHS = NO;
487 | CLANG_ANALYZER_NONNULL = YES;
488 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
489 | CLANG_CXX_LIBRARY = "libc++";
490 | CLANG_ENABLE_MODULES = YES;
491 | CLANG_ENABLE_OBJC_ARC = YES;
492 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
493 | CLANG_WARN_BOOL_CONVERSION = YES;
494 | CLANG_WARN_COMMA = YES;
495 | CLANG_WARN_CONSTANT_CONVERSION = YES;
496 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
497 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
498 | CLANG_WARN_EMPTY_BODY = YES;
499 | CLANG_WARN_ENUM_CONVERSION = YES;
500 | CLANG_WARN_INFINITE_RECURSION = YES;
501 | CLANG_WARN_INT_CONVERSION = YES;
502 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
503 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
504 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
505 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
506 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
507 | CLANG_WARN_STRICT_PROTOTYPES = YES;
508 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
509 | CLANG_WARN_UNREACHABLE_CODE = YES;
510 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
511 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
512 | COPY_PHASE_STRIP = NO;
513 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
514 | ENABLE_NS_ASSERTIONS = NO;
515 | ENABLE_STRICT_OBJC_MSGSEND = YES;
516 | GCC_C_LANGUAGE_STANDARD = gnu99;
517 | GCC_NO_COMMON_BLOCKS = YES;
518 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
519 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
520 | GCC_WARN_UNDECLARED_SELECTOR = YES;
521 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
522 | GCC_WARN_UNUSED_FUNCTION = YES;
523 | GCC_WARN_UNUSED_VARIABLE = YES;
524 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
525 | MTL_ENABLE_DEBUG_INFO = NO;
526 | SDKROOT = iphoneos;
527 | SUPPORTED_PLATFORMS = iphoneos;
528 | SWIFT_COMPILATION_MODE = wholemodule;
529 | SWIFT_OPTIMIZATION_LEVEL = "-O";
530 | TARGETED_DEVICE_FAMILY = "1,2";
531 | VALIDATE_PRODUCT = YES;
532 | };
533 | name = Release;
534 | };
535 | 97C147061CF9000F007C117D /* Debug */ = {
536 | isa = XCBuildConfiguration;
537 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
538 | buildSettings = {
539 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
540 | CLANG_ENABLE_MODULES = YES;
541 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
542 | ENABLE_BITCODE = NO;
543 | INFOPLIST_FILE = Runner/Info.plist;
544 | LD_RUNPATH_SEARCH_PATHS = (
545 | "$(inherited)",
546 | "@executable_path/Frameworks",
547 | );
548 | PRODUCT_BUNDLE_IDENTIFIER = com.example.fic11StarterPos;
549 | PRODUCT_NAME = "$(TARGET_NAME)";
550 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
551 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
552 | SWIFT_VERSION = 5.0;
553 | VERSIONING_SYSTEM = "apple-generic";
554 | };
555 | name = Debug;
556 | };
557 | 97C147071CF9000F007C117D /* Release */ = {
558 | isa = XCBuildConfiguration;
559 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
560 | buildSettings = {
561 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
562 | CLANG_ENABLE_MODULES = YES;
563 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
564 | ENABLE_BITCODE = NO;
565 | INFOPLIST_FILE = Runner/Info.plist;
566 | LD_RUNPATH_SEARCH_PATHS = (
567 | "$(inherited)",
568 | "@executable_path/Frameworks",
569 | );
570 | PRODUCT_BUNDLE_IDENTIFIER = com.example.fic11StarterPos;
571 | PRODUCT_NAME = "$(TARGET_NAME)";
572 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
573 | SWIFT_VERSION = 5.0;
574 | VERSIONING_SYSTEM = "apple-generic";
575 | };
576 | name = Release;
577 | };
578 | /* End XCBuildConfiguration section */
579 |
580 | /* Begin XCConfigurationList section */
581 | 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
582 | isa = XCConfigurationList;
583 | buildConfigurations = (
584 | 331C8088294A63A400263BE5 /* Debug */,
585 | 331C8089294A63A400263BE5 /* Release */,
586 | 331C808A294A63A400263BE5 /* Profile */,
587 | );
588 | defaultConfigurationIsVisible = 0;
589 | defaultConfigurationName = Release;
590 | };
591 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
592 | isa = XCConfigurationList;
593 | buildConfigurations = (
594 | 97C147031CF9000F007C117D /* Debug */,
595 | 97C147041CF9000F007C117D /* Release */,
596 | 249021D3217E4FDB00AE95B9 /* Profile */,
597 | );
598 | defaultConfigurationIsVisible = 0;
599 | defaultConfigurationName = Release;
600 | };
601 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
602 | isa = XCConfigurationList;
603 | buildConfigurations = (
604 | 97C147061CF9000F007C117D /* Debug */,
605 | 97C147071CF9000F007C117D /* Release */,
606 | 249021D4217E4FDB00AE95B9 /* Profile */,
607 | );
608 | defaultConfigurationIsVisible = 0;
609 | defaultConfigurationName = Release;
610 | };
611 | /* End XCConfigurationList section */
612 | };
613 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
614 | }
615 |
--------------------------------------------------------------------------------