mobile_team/lib/screens/project_form_screen.dart
2026-04-16 15:06:41 +05:30

134 lines
4.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../models/project_model.dart';
import '../services/project_service.dart';
class ProjectFormScreen extends StatefulWidget {
final ProjectModel? project;
const ProjectFormScreen({super.key, this.project});
@override
State<ProjectFormScreen> createState() => _ProjectFormScreenState();
}
class _ProjectFormScreenState extends State<ProjectFormScreen> {
final _formKey = GlobalKey<FormState>();
final _nameController = TextEditingController();
final _gitController = TextEditingController();
final _apiController = TextEditingController();
final _descriptionController = TextEditingController();
final _flavorsController = TextEditingController();
bool _isLoading = false;
@override
void initState() {
super.initState();
_nameController.text = widget.project?.name ?? '';
_gitController.text = widget.project?.gitUrl ?? '';
_apiController.text = widget.project?.apiDocUrl ?? '';
_descriptionController.text = widget.project?.description ?? '';
_flavorsController.text = widget.project?.flavors.join(', ') ?? '';
}
@override
void dispose() {
_nameController.dispose();
_gitController.dispose();
_apiController.dispose();
_descriptionController.dispose();
_flavorsController.dispose();
super.dispose();
}
void _submit() async {
if (!_formKey.currentState!.validate()) return;
setState(() => _isLoading = true);
final List<String> flavors = _flavorsController.text
.split(',')
.map((e) => e.trim())
.where((e) => e.isNotEmpty)
.toList();
final project = ProjectModel(
id: widget.project?.id ?? '',
name: _nameController.text.trim(),
gitUrl: _gitController.text.trim(),
apiDocUrl: _apiController.text.trim().isEmpty ? null : _apiController.text.trim(),
description: _descriptionController.text.trim(),
flavors: flavors,
createdAt: widget.project?.createdAt ?? DateTime.now(),
);
try {
if (widget.project == null) {
await context.read<ProjectService>().addProject(project);
} else {
await context.read<ProjectService>().updateProject(project);
}
if (mounted) Navigator.pop(context);
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Failed: $e")));
}
} finally {
if (mounted) setState(() => _isLoading = false);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.project == null ? "Create Project" : "Edit Project"),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _nameController,
decoration: const InputDecoration(labelText: "Project Name", border: OutlineInputBorder()),
validator: (v) => v!.isEmpty ? "Required" : null,
),
const SizedBox(height: 16),
TextFormField(
controller: _gitController,
decoration: const InputDecoration(labelText: "Git Repository URL", border: OutlineInputBorder()),
validator: (v) => v!.isEmpty ? "Required" : null,
),
const SizedBox(height: 16),
TextFormField(
controller: _apiController,
decoration: const InputDecoration(labelText: "API Documentation URL (Optional)", border: OutlineInputBorder()),
),
const SizedBox(height: 16),
TextFormField(
controller: _flavorsController,
decoration: const InputDecoration(
labelText: "Flavors (dev, prod, staging...)",
hintText: "Enter comma separated values",
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextFormField(
controller: _descriptionController,
maxLines: 5,
decoration: const InputDecoration(labelText: "Description", border: OutlineInputBorder()),
validator: (v) => v!.isEmpty ? "Required" : null,
),
const SizedBox(height: 32),
_isLoading
? const CircularProgressIndicator()
: ElevatedButton(onPressed: _submit, child: const Text("SAVE PROJECT")),
],
),
),
),
);
}
}