https://rega-softwareone.blogspot.com/2025/08/jastip-jus-sehat-di-kantin-smkn-1.html
import 'package:flutter/material.dart';
import 'dart:html' as html; // khusus Flutter Web untuk buka link
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Pesanan Online Kantin via anak rpl',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorSchemeSeed: Colors.teal,
useMaterial3: true,
),
home: const MenuPage(),
);
}
}
class MenuPage extends StatefulWidget {
const MenuPage({super.key});
@override
State<MenuPage> createState() => _MenuPageState();
}
class _MenuPageState extends State<MenuPage> {
final List<Map<String, dynamic>> menuItems = [
{"nama": "jus alpuket", "harga": 5000, "gambar": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRWWv1iXMc3SyUyOfS9UlakkjXOrKMWAHEXvA&s.jpg"},
{"nama": "jus jeruk", "harga": 5000, "gambar": "https://cdn.antaranews.com/cache/1200x800/2019/11/27/buah_1.jpg"},
{"nama": "jus jambu", "harga": 1000, "gambar": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtHxrk0GtXAZx_555As_7u03mhE9S4tbP86Q&s.jpg"},
];
final List<Map<String, dynamic>> keranjang = [];
void tambahKeKeranjang(Map<String, dynamic> item) {
setState(() {
keranjang.add(item);
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("${item['nama']} ditambahkan ke keranjang"),
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.teal,
),
);
}
void hapusDariKeranjang(int index) {
setState(() {
keranjang.removeAt(index);
});
}
int get totalBayar =>
keranjang.fold(0, (sum, item) => sum + (item['harga'] as int));
void kirimPesanWhatsApp() {
const String nomor = "6282228672037"; // nomor penjual WA
final String daftarPesanan = keranjang.map((item) {
return "- ${item['nama']} (Rp${item['harga']})";
}).join("\n");
final String total = "Total Bayar: Rp$totalBayar";
final String pesan = "Halo, saya ingin memesan:\n$daftarPesanan\n$total";
final String encodedPesan = Uri.encodeComponent(pesan);
final String url = "https://wa.me/$nomor?text=$encodedPesan";
// buka WhatsApp Web di tab baru
html.window.open(url, "_blank");
}
void bukaKeranjang() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.white,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
),
builder: (context) => DraggableScrollableSheet(
expand: false,
initialChildSize: 0.7,
builder: (context, scrollController) => Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Container(
width: 50,
height: 5,
margin: const EdgeInsets.only(bottom: 12),
decoration: BoxDecoration(
color: Colors.grey[400],
borderRadius: BorderRadius.circular(10),
),
),
const Text(
"Keranjang Pesanan",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const Divider(),
Expanded(
child: keranjang.isEmpty
? const Center(child: Text("Keranjang masih kosong."))
: ListView.builder(
controller: scrollController,
itemCount: keranjang.length,
itemBuilder: (context, index) {
final item = keranjang[index];
return Card(
margin: const EdgeInsets.symmetric(vertical: 6),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12)),
child: ListTile(
leading: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(
item['gambar'],
width: 50,
height: 50,
fit: BoxFit.cover,
),
),
title: Text(item['nama']),
subtitle: Text("Rp${item['harga']}"),
trailing: IconButton(
icon: const Icon(Icons.delete,
color: Colors.redAccent),
onPressed: () => hapusDariKeranjang(index),
),
),
);
},
),
),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Total: Rp$totalBayar",
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
FilledButton.icon(
onPressed: keranjang.isEmpty
? null
: () {
Navigator.pop(context);
kirimPesanWhatsApp();
},
icon: const Icon(Icons.send),
label: const Text("Pesan via WhatsApp"),
),
],
),
],
),
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
appBar: AppBar(
title: const Text("Pesanan Online Kantin"),
backgroundColor: Colors.teal,
foregroundColor: Colors.white,
elevation: 2,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(bottom: Radius.circular(16)),
),
actions: [
Stack(
children: [
IconButton(
icon: const Icon(Icons.shopping_cart),
onPressed: bukaKeranjang,
),
if (keranjang.isNotEmpty)
Positioned(
right: 8,
top: 8,
child: Container(
padding: const EdgeInsets.all(4),
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: Text(
"${keranjang.length}",
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold),
),
),
)
],
)
],
),
body: ListView.builder(
padding: const EdgeInsets.all(12),
itemCount: menuItems.length,
itemBuilder: (context, index) {
final item = menuItems[index];
return Card(
margin: const EdgeInsets.symmetric(vertical: 8),
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.network(
item['gambar'],
width: 70,
height: 70,
fit: BoxFit.cover,
),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(item['nama'],
style: const TextStyle(
fontSize: 16, fontWeight: FontWeight.bold)),
const SizedBox(height: 4),
Text("Rp${item['harga']}",
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
fontWeight: FontWeight.w500)),
],
),
),
FilledButton(
style: FilledButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 16, vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12)),
),
onPressed: () => tambahKeKeranjang(item),
child: const Text("Tambah"),
),
],
),
),
);
},
),
);
}
}


Komentar
Posting Komentar