Files
mcbeno-app/lib/services/auth_service.dart
b3ni15 871bfcdccb feat: Initialize Flutter app with authentication and scheduling features
- Removed TypeScript configuration file (tsconfig.json).
- Added Flutter plugin dependencies for secure storage.
- Implemented main application structure with routing for login, profile, and schedule screens.
- Developed LoginScreen with authentication logic and user feedback.
- Created ProfileScreen to display user profile information and logout functionality.
- Built ScheduleScreen to show weekly work schedule with navigation controls.
- Integrated AuthService for handling authentication, token storage, and API interactions.
- Updated pubspec.yaml with necessary dependencies for the Flutter project.
2025-08-20 22:48:54 +02:00

84 lines
2.5 KiB
Dart

import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart' as http;
class AuthService extends ChangeNotifier {
final _storage = const FlutterSecureStorage();
String? token;
Map<String, dynamic>? profile;
final _base = 'https://menuapi.devbeni.lol/api';
AuthService() {
_loadToken();
}
/// Convenience wrapper that returns the Data array for schedule or empty list
Future<List<dynamic>> fetchSchedule(int year, int month) async {
final resp = await _httpGet('/@me/schedule?year=$year&month=$month');
if (resp == null) return [];
try {
if (resp['data'] != null && resp['data']['Data'] is List) {
return List<dynamic>.from(resp['data']['Data']);
}
} catch (e) {
return [];
}
return [];
}
Future<void> loadProfile() async {
if (token == null) return;
final res = await http.get(
Uri.parse('https://menuapi.devbeni.lol/api/me'),
headers: {'Authorization': 'Bearer $token'},
);
if (res.statusCode == 200) {
profile = jsonDecode(res.body)['data'];
notifyListeners();
}
}
Future<bool> login(String username, String password) async {
try {
final res = await http.post(
Uri.parse('$_base/login'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'username': username, 'password': password}),
);
if (res.statusCode != 200) return false;
final data = jsonDecode(res.body);
// token might be in different places; try common keys
token = data['token'] ?? data['access_token'] ?? (data['data'] != null ? data['data']['token'] : null);
if (token == null) return false;
await _storage.write(key: 'token', value: token);
await loadProfile();
notifyListeners();
return true;
} catch (e) {
return false;
}
}
Future<void> logout() async {
token = null;
profile = null;
await _storage.delete(key: 'token');
notifyListeners();
}
Future<dynamic> _httpGet(String path) async {
if (token == null) return null;
final res = await http.get(Uri.parse('$_base$path'), headers: {'Authorization': 'Bearer $token'});
if (res.statusCode == 200) return jsonDecode(res.body);
return null;
}
Future<void> _loadToken() async {
token = await _storage.read(key: 'token');
if (token != null) await loadProfile();
notifyListeners();
}
}