134 lines
4.6 KiB
Dart
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")),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|