marco.pms.mobileapp/lib/model/directory/create_bucket_bottom_sheet.dart

172 lines
7.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:marco/controller/directory/create_bucket_controller.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text_style.dart';
class CreateBucketBottomSheet extends StatefulWidget {
const CreateBucketBottomSheet({super.key});
@override
State<CreateBucketBottomSheet> createState() => _CreateBucketBottomSheetState();
}
class _CreateBucketBottomSheetState extends State<CreateBucketBottomSheet> {
final BucketController _controller = Get.put(BucketController());
final _formKey = GlobalKey<FormState>();
InputDecoration _inputDecoration(String hint) {
return InputDecoration(
hintText: hint,
hintStyle: MyTextStyle.bodySmall(xMuted: true),
filled: true,
fillColor: Colors.grey.shade100,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey.shade300),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey.shade300),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.blueAccent, width: 1.5),
),
contentPadding: MySpacing.all(16),
);
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return GetBuilder<BucketController>(
builder: (_) {
return SafeArea(
top: false,
child: SingleChildScrollView(
padding: MediaQuery.of(context).viewInsets,
child: Container(
decoration: BoxDecoration(
color: theme.cardColor,
borderRadius: const BorderRadius.vertical(top: Radius.circular(24)),
boxShadow: const [
BoxShadow(color: Colors.black12, blurRadius: 12, offset: Offset(0, -2)),
],
),
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 16, 20, 32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 40,
height: 5,
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(10),
),
),
MySpacing.height(12),
Text("Create New Bucket", style: MyTextStyle.titleLarge(fontWeight: 700)),
MySpacing.height(24),
Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.labelMedium("Bucket Name"),
MySpacing.height(8),
TextFormField(
initialValue: _controller.name.value,
onChanged: _controller.updateName,
validator: (value) {
if (value == null || value.trim().isEmpty) {
return "Bucket name is required";
}
return null;
},
decoration: _inputDecoration("e.g., Project Docs"),
),
MySpacing.height(16),
MyText.labelMedium("Description"),
MySpacing.height(8),
TextFormField(
initialValue: _controller.description.value,
onChanged: _controller.updateDescription,
maxLines: 3,
decoration: _inputDecoration("Optional bucket description"),
),
MySpacing.height(24),
Row(
children: [
Expanded(
child: OutlinedButton.icon(
onPressed: () => Navigator.pop(context, false),
icon: const Icon(Icons.close, color: Colors.red),
label: MyText.bodyMedium("Cancel", color: Colors.red, fontWeight: 600),
style: OutlinedButton.styleFrom(
side: const BorderSide(color: Colors.red),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 14),
),
),
),
MySpacing.width(12),
Expanded(
child: Obx(() {
return ElevatedButton.icon(
onPressed: _controller.isCreating.value
? null
: () async {
if (_formKey.currentState!.validate()) {
await _controller.createBucket();
}
},
icon: _controller.isCreating.value
? const SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
)
: const Icon(Icons.check_circle_outline, color: Colors.white),
label: MyText.bodyMedium(
_controller.isCreating.value ? "Creating..." : "Create",
color: Colors.white,
fontWeight: 600,
),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.indigo,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 14),
),
);
}),
),
],
),
],
),
),
],
),
),
),
),
);
},
);
}
@override
void dispose() {
Get.delete<BucketController>();
super.dispose();
}
}