113 lines
3.6 KiB
Dart
113 lines
3.6 KiB
Dart
// lib/features/feedback/feedback_provider.dart
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../../core/network/api_client.dart';
|
|
import 'feedback_model.dart';
|
|
|
|
// ──────────────────────────────────────────
|
|
// Service
|
|
// ──────────────────────────────────────────
|
|
class FeedbackService {
|
|
final Dio _dio;
|
|
FeedbackService(this._dio);
|
|
|
|
Future<void> submit(FeedbackRequest req) async {
|
|
await _dio.post<void>('/feedback', data: req.toJson());
|
|
}
|
|
}
|
|
|
|
final feedbackServiceProvider = Provider<FeedbackService>(
|
|
(ref) => FeedbackService(ref.read(apiClientProvider)),
|
|
);
|
|
|
|
// ──────────────────────────────────────────
|
|
// Estado del formulario
|
|
// ──────────────────────────────────────────
|
|
enum FeedbackFormStatus { idle, loading, success, error }
|
|
|
|
class FeedbackFormState {
|
|
final FeedbackType selectedType;
|
|
final int rating;
|
|
final String message;
|
|
final FeedbackFormStatus status;
|
|
final String? errorMessage;
|
|
|
|
const FeedbackFormState({
|
|
this.selectedType = FeedbackType.noPaso,
|
|
this.rating = 3,
|
|
this.message = '',
|
|
this.status = FeedbackFormStatus.idle,
|
|
this.errorMessage,
|
|
});
|
|
|
|
FeedbackFormState copyWith({
|
|
FeedbackType? selectedType,
|
|
int? rating,
|
|
String? message,
|
|
FeedbackFormStatus? status,
|
|
String? errorMessage,
|
|
}) {
|
|
return FeedbackFormState(
|
|
selectedType: selectedType ?? this.selectedType,
|
|
rating: rating ?? this.rating,
|
|
message: message ?? this.message,
|
|
status: status ?? this.status,
|
|
errorMessage: errorMessage ?? this.errorMessage,
|
|
);
|
|
}
|
|
}
|
|
|
|
// ──────────────────────────────────────────
|
|
// Notifier
|
|
// ──────────────────────────────────────────
|
|
class FeedbackNotifier extends Notifier<FeedbackFormState> {
|
|
@override
|
|
FeedbackFormState build() => const FeedbackFormState();
|
|
|
|
void setType(FeedbackType type) => state = state.copyWith(selectedType: type);
|
|
|
|
void setRating(int r) => state = state.copyWith(rating: r);
|
|
|
|
void setMessage(String m) => state = state.copyWith(message: m);
|
|
|
|
void reset() => state = const FeedbackFormState();
|
|
|
|
Future<void> submit({
|
|
required String addressId,
|
|
required String unitId,
|
|
}) async {
|
|
state = state.copyWith(status: FeedbackFormStatus.loading);
|
|
try {
|
|
final req = FeedbackRequest(
|
|
addressId: addressId,
|
|
type: state.selectedType,
|
|
rating: state.rating,
|
|
message: state.message,
|
|
targetUnitId: unitId,
|
|
);
|
|
await ref.read(feedbackServiceProvider).submit(req);
|
|
state = state.copyWith(status: FeedbackFormStatus.success);
|
|
} on DioException catch (e) {
|
|
final data = e.response?.data;
|
|
final detail = (data is Map && data['detail'] != null)
|
|
? data['detail'].toString()
|
|
: null;
|
|
state = state.copyWith(
|
|
status: FeedbackFormStatus.error,
|
|
errorMessage: detail ?? e.message ?? 'Error al enviar',
|
|
);
|
|
} catch (e) {
|
|
state = state.copyWith(
|
|
status: FeedbackFormStatus.error,
|
|
errorMessage: 'Error al enviar: $e',
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
final feedbackProvider = NotifierProvider<FeedbackNotifier, FeedbackFormState>(
|
|
FeedbackNotifier.new,
|
|
);
|