143 lines
4.6 KiB
Dart
143 lines
4.6 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:uuid/uuid.dart';
|
|
import '../api_service.dart';
|
|
import '../profile_manager.dart';
|
|
|
|
class AddSiteScreen extends StatefulWidget {
|
|
const AddSiteScreen({super.key});
|
|
|
|
@override
|
|
State<AddSiteScreen> createState() => _AddSiteScreenState();
|
|
}
|
|
|
|
class _AddSiteScreenState extends State<AddSiteScreen> {
|
|
final _nameController = TextEditingController();
|
|
final _urlController = TextEditingController();
|
|
final _keyController = TextEditingController();
|
|
final _secretController = TextEditingController();
|
|
bool _isLoading = false;
|
|
|
|
String _getPlatformHint() {
|
|
if (kIsWeb) return 'e.g. localhost:8000';
|
|
if (defaultTargetPlatform == TargetPlatform.android) return 'e.g. 10.0.2.2:8000';
|
|
return 'e.g. localhost:8000';
|
|
}
|
|
|
|
void _handleSave() async {
|
|
if (_nameController.text.isEmpty ||
|
|
_urlController.text.isEmpty ||
|
|
_keyController.text.isEmpty ||
|
|
_secretController.text.isEmpty) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(content: Text('Please fill all fields')),
|
|
);
|
|
return;
|
|
}
|
|
|
|
setState(() => _isLoading = true);
|
|
|
|
try {
|
|
final api = Provider.of<ApiService>(context, listen: false);
|
|
final profile = Provider.of<ProfileManager>(context, listen: false);
|
|
|
|
// Verify Direct Connection
|
|
await api.verifyCredentials(
|
|
_urlController.text,
|
|
_keyController.text,
|
|
_secretController.text
|
|
);
|
|
|
|
// Normalize Target URL for saving
|
|
String targetUrl = _urlController.text.trim();
|
|
if (!targetUrl.startsWith('http')) targetUrl = 'https://$targetUrl';
|
|
if (targetUrl.endsWith('/')) targetUrl = targetUrl.substring(0, targetUrl.length - 1);
|
|
|
|
await profile.addSite(SiteConfig(
|
|
id: const Uuid().v4(),
|
|
name: _nameController.text,
|
|
url: targetUrl,
|
|
consumerKey: _keyController.text,
|
|
consumerSecret: _secretController.text,
|
|
));
|
|
|
|
if (mounted) {
|
|
Navigator.pop(context);
|
|
}
|
|
|
|
} catch (e) {
|
|
if (mounted) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(content: Text('Connection failed: $e'), backgroundColor: Colors.red),
|
|
);
|
|
}
|
|
} finally {
|
|
if (mounted) setState(() => _isLoading = false);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('Add Store')),
|
|
body: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(24),
|
|
child: Column(
|
|
children: [
|
|
TextField(
|
|
controller: _nameController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Store Name',
|
|
hintText: 'e.g. Shoe Store',
|
|
prefixIcon: Icon(Icons.store),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
TextField(
|
|
controller: _urlController,
|
|
decoration: InputDecoration(
|
|
labelText: 'Store URL',
|
|
hintText: _getPlatformHint(),
|
|
prefixIcon: const Icon(Icons.link),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
TextField(
|
|
controller: _keyController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Consumer Key',
|
|
prefixIcon: Icon(Icons.key),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
TextField(
|
|
controller: _secretController,
|
|
obscureText: true,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Consumer Secret',
|
|
prefixIcon: Icon(Icons.lock),
|
|
),
|
|
),
|
|
const SizedBox(height: 32),
|
|
SizedBox(
|
|
width: double.infinity,
|
|
child: ElevatedButton(
|
|
onPressed: _isLoading ? null : _handleSave,
|
|
style: ElevatedButton.styleFrom(
|
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
|
backgroundColor: Colors.blue,
|
|
foregroundColor: Colors.white,
|
|
),
|
|
child: _isLoading
|
|
? const SizedBox(height: 20, width: 20, child: CircularProgressIndicator(strokeWidth: 2))
|
|
: const Text('Verify & Save'),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|