135 lines
3.7 KiB
Dart
135 lines
3.7 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:http/http.dart' as http;
|
|
|
|
import '../models/venue.dart';
|
|
import '../services/remote_sync_service.dart';
|
|
import '../utils/app_config.dart';
|
|
|
|
enum RegistrationStep { initial, loadingVenues, venuesLoaded, error, registering, registered }
|
|
|
|
class RegistrationViewModel extends ChangeNotifier {
|
|
final RemoteSyncService syncService;
|
|
|
|
RegistrationViewModel({required this.syncService});
|
|
|
|
RegistrationStep _step = RegistrationStep.initial;
|
|
RegistrationStep get step => _step;
|
|
|
|
List<Venue> _venues = [];
|
|
List<Venue> get venues => _venues;
|
|
|
|
Venue? _selectedVenue;
|
|
Venue? get selectedVenue => _selectedVenue;
|
|
|
|
String? _errorMessage;
|
|
String? get errorMessage => _errorMessage;
|
|
|
|
void selectVenue(Venue venue) {
|
|
_selectedVenue = venue;
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> fetchVenues() async {
|
|
_step = RegistrationStep.loadingVenues;
|
|
_errorMessage = null;
|
|
notifyListeners();
|
|
|
|
try {
|
|
final response = await http
|
|
.get(Uri.parse('$kRemoteServerUrl/venues/'))
|
|
.timeout(const Duration(seconds: 15));
|
|
|
|
if (response.statusCode == 200) {
|
|
final List<dynamic> data = jsonDecode(response.body) as List<dynamic>;
|
|
_venues = data
|
|
.map((e) => Venue.fromJson(e as Map<String, dynamic>))
|
|
.toList();
|
|
_step = RegistrationStep.venuesLoaded;
|
|
} else {
|
|
_errorMessage = 'Failed to load venues (HTTP ${response.statusCode})';
|
|
_step = RegistrationStep.error;
|
|
}
|
|
} catch (e) {
|
|
debugPrint('RegistrationViewModel: fetchVenues error: $e');
|
|
_errorMessage = e.toString();
|
|
_step = RegistrationStep.error;
|
|
}
|
|
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<bool> registerDevice({
|
|
required String deviceName,
|
|
required String registrationCode,
|
|
}) async {
|
|
final venue = _selectedVenue;
|
|
if (venue == null) return false;
|
|
|
|
_step = RegistrationStep.registering;
|
|
_errorMessage = null;
|
|
notifyListeners();
|
|
|
|
try {
|
|
final response = await http
|
|
.post(
|
|
Uri.parse('$kRemoteServerUrl/devices/register'),
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: jsonEncode({
|
|
'venueId': venue.id,
|
|
'name': deviceName,
|
|
'registrationCode': registrationCode,
|
|
}),
|
|
)
|
|
.timeout(const Duration(seconds: 15));
|
|
|
|
if (response.statusCode == 201) {
|
|
final data = jsonDecode(response.body) as Map<String, dynamic>;
|
|
final deviceId = data['deviceId'] as String;
|
|
final token = data['token'] as String;
|
|
|
|
await syncService.setCredentials(
|
|
deviceId: deviceId,
|
|
token: token,
|
|
venueId: venue.id,
|
|
serverUrl: kRemoteServerUrl,
|
|
);
|
|
|
|
_step = RegistrationStep.registered;
|
|
notifyListeners();
|
|
return true;
|
|
} else {
|
|
String message;
|
|
try {
|
|
final errorData = jsonDecode(response.body) as Map<String, dynamic>;
|
|
message = errorData['message'] as String? ?? 'Registration failed';
|
|
} catch (_) {
|
|
message = 'Registration failed (HTTP ${response.statusCode})';
|
|
}
|
|
_errorMessage = message;
|
|
_step = RegistrationStep.venuesLoaded;
|
|
notifyListeners();
|
|
return false;
|
|
}
|
|
} catch (e) {
|
|
debugPrint('RegistrationViewModel: registerDevice error: $e');
|
|
_errorMessage = e.toString();
|
|
_step = RegistrationStep.venuesLoaded;
|
|
notifyListeners();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<void> retry() async {
|
|
await fetchVenues();
|
|
}
|
|
|
|
void reset() {
|
|
_step = RegistrationStep.initial;
|
|
_venues = [];
|
|
_selectedVenue = null;
|
|
_errorMessage = null;
|
|
notifyListeners();
|
|
}
|
|
} |