Files
Avtex/lib/screens/gitea_sync_settings_screen.dart
T

204 lines
7.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../providers/gitea_sync_provider.dart';
class GiteaSyncSettingsScreen extends ConsumerStatefulWidget {
const GiteaSyncSettingsScreen({super.key});
@override
ConsumerState<GiteaSyncSettingsScreen> createState() => _GiteaSyncSettingsScreenState();
}
class _GiteaSyncSettingsScreenState extends ConsumerState<GiteaSyncSettingsScreen> {
final _formKey = GlobalKey<FormState>();
final _urlCtrl = TextEditingController(text: 'http://git.a-crm.controlsystem.kz');
final _tokenCtrl = TextEditingController();
final _ownerCtrl = TextEditingController(text: 'Alexyz');
final _repoCtrl = TextEditingController(text: 'CMMNANAXE-CRM');
bool _testing = false;
@override
void dispose() {
_urlCtrl.dispose();
_tokenCtrl.dispose();
_ownerCtrl.dispose();
_repoCtrl.dispose();
super.dispose();
}
Future<void> _testAndSave() async {
if (!_formKey.currentState!.validate()) return;
setState(() => _testing = true);
final notifier = ref.read(mindmapSyncProvider.notifier);
try {
await notifier.configure(
baseUrl: _urlCtrl.text.trim(),
token: _tokenCtrl.text.trim(),
owner: _ownerCtrl.text.trim(),
repo: _repoCtrl.text.trim(),
);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Подключение к Gitea установлено')),
);
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Ошибка: $e'), backgroundColor: Colors.red),
);
}
} finally {
if (mounted) setState(() => _testing = false);
}
}
Future<void> _syncNow() async {
setState(() => _testing = true);
final notifier = ref.read(mindmapSyncProvider.notifier);
try {
await notifier.syncFromGitea();
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Синхронизация завершена')),
);
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Ошибка синхронизации: $e'), backgroundColor: Colors.red),
);
}
} finally {
if (mounted) setState(() => _testing = false);
}
}
@override
Widget build(BuildContext context) {
final state = ref.watch(mindmapSyncProvider);
return Scaffold(
appBar: AppBar(
title: const Text('Синхронизация с Gitea'),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => context.pop(),
),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: ListView(
children: [
// Статус
Card(
child: ListTile(
leading: Icon(
state.isConfigured ? Icons.cloud_done : Icons.cloud_off,
color: state.isConfigured ? Colors.green : Colors.grey,
),
title: Text(
state.isConfigured ? 'Подключено к Gitea' : 'Не подключено',
style: Theme.of(context).textTheme.titleMedium,
),
subtitle: state.isSyncing
? const Text('Синхронизация...')
: state.error != null
? Text('Ошибка: ${state.error}')
: const Text('Настройте подключение ниже'),
),
),
const SizedBox(height: 16),
// URL
TextFormField(
controller: _urlCtrl,
decoration: const InputDecoration(
labelText: 'Gitea URL',
hintText: 'http://git.a-crm.controlsystem.kz',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.link),
),
validator: (v) => v == null || v.isEmpty ? 'Укажите URL' : null,
),
const SizedBox(height: 12),
// Token
TextFormField(
controller: _tokenCtrl,
decoration: const InputDecoration(
labelText: 'Access Token',
hintText: 'Ваш токен из Gitea (Settings → Applications)',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.key),
),
obscureText: true,
validator: (v) => v == null || v.isEmpty ? 'Укажите токен' : null,
),
const SizedBox(height: 12),
// Owner
TextFormField(
controller: _ownerCtrl,
decoration: const InputDecoration(
labelText: 'Owner (пользователь/организация)',
hintText: 'Alexyz',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.person),
),
validator: (v) => v == null || v.isEmpty ? 'Укажите владельца' : null,
),
const SizedBox(height: 12),
// Repo
TextFormField(
controller: _repoCtrl,
decoration: const InputDecoration(
labelText: 'Repository',
hintText: 'CMMNANAXE-CRM',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.folder),
),
validator: (v) => v == null || v.isEmpty ? 'Укажите репозиторий' : null,
),
const SizedBox(height: 24),
// Кнопки
ElevatedButton.icon(
onPressed: _testing ? null : _testAndSave,
icon: _testing
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.save),
label: const Text('Сохранить и проверить'),
),
const SizedBox(height: 12),
if (state.isConfigured)
ElevatedButton.icon(
onPressed: _testing ? null : _syncNow,
icon: const Icon(Icons.sync),
label: const Text('Синхронизировать сейчас'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
foregroundColor: Colors.white,
),
),
],
),
),
),
);
}
}