2025-08-08 14:59:49 +07:00

183 lines
5.7 KiB
Dart

import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:enaklo_pos/data/models/response/table_model.dart';
import 'package:enaklo_pos/presentation/table/pages/table_page.dart';
import 'package:flutter/material.dart';
class TableWidget extends StatelessWidget {
final TableModel table;
final bool isSelected;
const TableWidget({super.key, required this.table, this.isSelected = false});
// Fungsi untuk menentukan jumlah kursi di tiap sisi
Map<String, int> getChairDistribution(int capacity) {
if (capacity == 1) {
return {'top': 0, 'bottom': 0, 'left': 1, 'right': 0};
} else if (capacity == 2) {
return {'top': 0, 'bottom': 0, 'left': 1, 'right': 1};
} else if (capacity == 3) {
return {'top': 1, 'bottom': 0, 'left': 1, 'right': 1};
} else if (capacity == 4) {
return {'top': 1, 'bottom': 1, 'left': 1, 'right': 1};
} else if (capacity == 5) {
return {'top': 2, 'bottom': 1, 'left': 1, 'right': 1};
} else if (capacity == 6) {
return {'top': 2, 'bottom': 2, 'left': 1, 'right': 1};
} else if (capacity == 7) {
return {'top': 3, 'bottom': 2, 'left': 1, 'right': 1};
} else if (capacity == 8) {
return {'top': 3, 'bottom': 3, 'left': 1, 'right': 1};
} else if (capacity == 9) {
return {'top': 4, 'bottom': 3, 'left': 1, 'right': 1};
} else if (capacity == 10) {
return {'top': 4, 'bottom': 4, 'left': 1, 'right': 1};
} else {
int side = ((capacity - 2) / 2).floor();
return {'top': side, 'bottom': side, 'left': 1, 'right': 1};
}
}
Color getStatusColor() {
switch (parseStatus(table.status)) {
case TableStatus.available:
return Colors.blue[100]!;
case TableStatus.occupied:
return Colors.orange[100]!;
case TableStatus.billed:
return Colors.green[100]!;
case TableStatus.availableSoon:
return Colors.yellow[100]!;
default:
return Colors.grey[200]!;
}
}
Color getBorderColor() {
if (isSelected) return AppColors.primary;
switch (parseStatus(table.status)) {
case TableStatus.available:
return Colors.blue;
case TableStatus.occupied:
return Colors.orange;
case TableStatus.billed:
return Colors.green;
case TableStatus.availableSoon:
return Colors.yellow[700]!;
default:
return Colors.grey;
}
}
@override
Widget build(BuildContext context) {
final int capacity = table.capacity ?? 0;
final chairDist = getChairDistribution(capacity);
Widget chair() => Container(
width: 20,
height: 10,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(4),
),
);
return Container(
width: (table.capacity ?? 0) > 16
? 240
: (table.capacity ?? 0) > 8
? 180
: 120,
height: 80,
child: Stack(
alignment: Alignment.center,
children: [
// Meja utama
Container(
width: (table.capacity ?? 0) > 16
? 220
: (table.capacity ?? 0) > 8
? 160
: 100,
height: 60,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: getBorderColor(),
width: 2,
),
borderRadius: BorderRadius.circular(16),
),
child: Center(
child: CircleAvatar(
radius: 24,
backgroundColor: getStatusColor(),
child: Text(
table.tableName ?? "",
style: TextStyle(
color: getBorderColor(),
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
),
),
),
// Kursi atas
if (chairDist['top']! > 0)
Positioned(
top: 0,
left: 10,
right: 10,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(chairDist['top']!, (_) => chair()),
),
),
// Kursi bawah
if (chairDist['bottom']! > 0)
Positioned(
bottom: 0,
left: 10,
right: 10,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(chairDist['bottom']!, (_) => chair()),
),
),
// Kursi kiri
if (chairDist['left']! > 0)
Positioned(
left: 0,
top: 15,
bottom: 15,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(chairDist['left']!, (_) => chair()),
),
),
// Kursi kanan
if (chairDist['right']! > 0)
Positioned(
right: 0,
top: 15,
bottom: 15,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(chairDist['right']!, (_) => chair()),
),
),
// Icon info kecil di pojok kanan atas jika status reserved
if (parseStatus(table.status) == TableStatus.occupied)
const Positioned(
top: 6,
right: 6,
child:
Icon(Icons.info_outline, size: 16, color: Colors.redAccent),
),
],
),
);
}
}