Kasir Grosir: starter Flutter POS (scaffold awal)

This commit is contained in:
onie
2026-10-17 13:10:06 +07:00
commit 636579a0d2
146 changed files with 5373 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class AccountsReceivableScreen extends StatelessWidget {
const AccountsReceivableScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const TemplateScreen(
title: 'Accounts Receivable',
drawer: AppDrawer(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Piutang (AR)', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text('TODO: Invoices, partial payments, aging report.'),
SizedBox(height: 12),
Text('Catatan:'),
Text('- Implement invoice model and payment entries.'),
],
),
);
}
}

View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class CustomersScreen extends StatelessWidget {
const CustomersScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const TemplateScreen(
title: 'Customers',
drawer: AppDrawer(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Pelanggan', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text('TODO: Customer list, price tier, credit limit, contact info.'),
SizedBox(height: 12),
Text('Catatan:'),
Text('- Simpan informasi credit limit & term_days untuk AR.'),
Text('- Integrate quick select from POS.'),
],
),
);
}
}

View File

@@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class DashboardScreen extends StatelessWidget {
const DashboardScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const TemplateScreen(
title: 'Dashboard',
drawer: AppDrawer(),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Ringkasan Harian', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text('- Penjualan hari ini: TODO (implement)') ,
Text('- Piutang terutang: TODO (implement)'),
Text('- Stok kritis: TODO (implement)'),
SizedBox(height: 24),
Text('Catatan:', style: TextStyle(fontWeight: FontWeight.bold)),
Text('1. Ambil data penjualan lokal (SQLite) dan agregasi untuk ringkasan.'),
Text('2. Buat widget chart sederhana setelah data tersedia.'),
],
),
),
);
}
}

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class InventoryScreen extends StatelessWidget {
const InventoryScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const TemplateScreen(
title: 'Inventory',
drawer: AppDrawer(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Stok & Warehousing', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text('TODO: Multi-warehouse, stock adjustment, transfers.'),
SizedBox(height: 12),
Text('Catatan:'),
Text('- Keep stock movements log for audit.'),
],
),
);
}
}

51
lib/screens/pos.dart Normal file
View File

@@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class PosScreen extends StatelessWidget {
const PosScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return TemplateScreen(
title: 'POS',
drawer: const AppDrawer(),
fab: FloatingActionButton(
onPressed: () {},
tooltip: 'New Transaction',
child: const Icon(Icons.add),
),
body: Column(
children: [
Card(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
children: const [
Icon(Icons.search),
SizedBox(width: 8),
Expanded(child: TextField(decoration: InputDecoration.collapsed(hintText: 'Search products'))),
],
),
),
),
const SizedBox(height: 12),
Expanded(
child: GridView.builder(
itemCount: 12,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 0.9),
itemBuilder: (context, i) {
return Card(
child: InkWell(
onTap: () {},
child: Center(child: Text('Product ${i + 1}', textAlign: TextAlign.center)),
),
);
},
),
),
],
),
);
}
}

27
lib/screens/products.dart Normal file
View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class ProductsScreen extends StatelessWidget {
const ProductsScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const TemplateScreen(
title: 'Products',
drawer: AppDrawer(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Produk / Katalog', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text('TODO: Implement CRUD produk (SKU, barcode, harga, stok, unit, pack).'),
SizedBox(height: 12),
Text('Catatan:'),
Text('- Buat Room/SQLite entity untuk product.'),
Text('- Tambahkan import CSV untuk bulk upload.'),
],
),
);
}
}

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class PurchaseOrdersScreen extends StatelessWidget {
const PurchaseOrdersScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const TemplateScreen(
title: 'Purchase Orders',
drawer: AppDrawer(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Purchase Orders', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text('TODO: Create PO, receive partial/full, update stock & cost.'),
SizedBox(height: 12),
Text('Catatan:'),
Text('- Track expected_date & received_status.'),
],
),
);
}
}

26
lib/screens/reports.dart Normal file
View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class ReportsScreen extends StatelessWidget {
const ReportsScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const TemplateScreen(
title: 'Reports',
drawer: AppDrawer(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Laporan', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text('TODO: Sales per day, per product, AR aging, inventory valuation.'),
SizedBox(height: 12),
Text('Catatan:'),
Text('- Start with CSV export and simple list views.'),
],
),
);
}
}

26
lib/screens/settings.dart Normal file
View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class SettingsScreen extends StatelessWidget {
const SettingsScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const TemplateScreen(
title: 'Settings',
drawer: AppDrawer(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Pengaturan', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text('TODO: Store profile, tax settings, printer config, backup/restore.'),
SizedBox(height: 12),
Text('Catatan:'),
Text('- Add page to configure Bluetooth printer later.'),
],
),
);
}
}

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class SuppliersScreen extends StatelessWidget {
const SuppliersScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const TemplateScreen(
title: 'Suppliers',
drawer: AppDrawer(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Supplier', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text('TODO: Supplier master, PO creation and contact info.'),
SizedBox(height: 12),
Text('Catatan:'),
Text('- Implement PO flow: create, send, receive.'),
],
),
);
}
}

26
lib/screens/users.dart Normal file
View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class UsersScreen extends StatelessWidget {
const UsersScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const TemplateScreen(
title: 'Users',
drawer: AppDrawer(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('User Management', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text('TODO: Roles & permissions (admin, kasir, gudang, sales).'),
SizedBox(height: 12),
Text('Catatan:'),
Text('- Implement simple local PIN auth for kasir initially.'),
],
),
);
}
}

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import '../widgets/template_screen.dart';
import '../widgets/app_drawer.dart';
class UtilitiesScreen extends StatelessWidget {
const UtilitiesScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const TemplateScreen(
title: 'Utilities',
drawer: AppDrawer(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Utilities', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
Text('TODO: Import/Export CSV, label printing, backup/restore.'),
SizedBox(height: 12),
Text('Catatan:'),
Text('- Provide CSV templates for bulk import.'),
],
),
);
}
}