Update Saqel Platform: 2026-09-08 17:51:07

This commit is contained in:
Hamza-Ayed
2026-09-08 17:51:07 +03:00
parent 902cf00152
commit 75451ebc3f
12 changed files with 84 additions and 39 deletions
@@ -6,6 +6,9 @@ import '../utils/app_logger.dart';
/// Enterprise Storage Service with Device-Bound Payload Obfuscation & Secure KeyStore/Keychain
class StorageService {
// Keeps a newly issued session available during this app run if the macOS
// debug runner has no Keychain entitlement. Production still uses Keychain.
static final Map<String, String> _volatileStore = <String, String>{};
final FlutterSecureStorage _secureStorage;
StorageService({FlutterSecureStorage? secureStorage})
@@ -26,6 +29,7 @@ class StorageService {
static const String _keyDeviceId = 'saqel_device_id';
Future<void> _writeSafe(String key, String value) async {
_volatileStore[key] = value;
try {
await _secureStorage.write(key: key, value: value);
} on PlatformException catch (e) {
@@ -38,10 +42,11 @@ class StorageService {
final val = await _secureStorage.read(key: key);
if (val != null && val.isNotEmpty) return val;
} catch (_) {}
return null;
return _volatileStore[key];
}
Future<void> _deleteSafe(String key) async {
_volatileStore.remove(key);
try {
await _secureStorage.delete(key: key);
} catch (_) {}
@@ -88,7 +88,7 @@ class AuthRepository {
required String identityToken,
required String fullName,
required String nationalId,
String gradeLevel = 'tawjihi_2008',
String gradeLevel = 'grade_10',
String stream = 'scientific',
}) async {
final res = await _api.post(
@@ -148,7 +148,7 @@ class AuthCubit extends Cubit<AuthState> {
required String identityToken,
required String fullName,
required String nationalId,
String gradeLevel = 'tawjihi_2008',
String gradeLevel = 'grade_10',
String stream = 'scientific',
}) async {
AppLogger.log('Setting up profile for $fullName ($nationalId)...', tag: 'AUTH_CUBIT');
@@ -23,7 +23,7 @@ class _AuthScreenState extends State<AuthScreen> {
final TextEditingController _fullNameController = TextEditingController();
String _selectedRole = 'student';
final String _selectedGrade = 'tawjihi_2008';
String _selectedGrade = 'grade_10';
String _selectedStream = 'scientific';
@override
@@ -440,7 +440,30 @@ class _AuthScreenState extends State<AuthScreen> {
),
const SizedBox(height: 18),
// Stream Selector (العلمي / الأدبي)
Text(
'الصف الدراسي',
style: AppTypography.titleMedium.copyWith(color: AppColors.textSecondaryDark, fontSize: 13),
),
const SizedBox(height: 8),
Wrap(
spacing: 8,
children: [
('grade_10', 'الصف العاشر'),
('grade_11', 'الأول ثانوي'),
('grade_12', 'الثاني ثانوي'),
].map((grade) => ChoiceChip(
label: Text(grade.$2),
selected: _selectedGrade == grade.$1,
onSelected: isLoading ? null : (_) => setState(() {
_selectedGrade = grade.$1;
if (_selectedGrade == 'grade_10') _selectedStream = 'general';
}),
)).toList(),
),
const SizedBox(height: 18),
// Stream Selector (only secondary grades have a stream)
if (_selectedGrade != 'grade_10') ...[
Text(
'الفرع الأكاديمي',
style: AppTypography.titleMedium.copyWith(color: AppColors.textSecondaryDark, fontSize: 13),
@@ -501,6 +524,7 @@ class _AuthScreenState extends State<AuthScreen> {
),
],
),
],
const SizedBox(height: 24),
LuxuryButton(