295 lines
9.8 KiB
Dart
295 lines
9.8 KiB
Dart
import '../core/utils/safe_convert.dart';
|
|
|
|
class NamedRecord {
|
|
final int id;
|
|
final String name;
|
|
|
|
const NamedRecord({required this.id, required this.name});
|
|
|
|
factory NamedRecord.fromJson(Map<String, dynamic> json) {
|
|
return NamedRecord(
|
|
id: SafeConvert.toSafeInt(json['id']),
|
|
name: SafeConvert.toSafeString(json['name']),
|
|
);
|
|
}
|
|
|
|
static NamedRecord? fromNullableJson(dynamic json) {
|
|
final map = SafeConvert.toNullableMap(json);
|
|
if (map == null) return null;
|
|
return NamedRecord.fromJson(map);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() => {'id': id, 'name': name};
|
|
|
|
@override
|
|
String toString() => name;
|
|
}
|
|
|
|
class StudentBasic {
|
|
final int id;
|
|
final String name;
|
|
|
|
const StudentBasic({required this.id, required this.name});
|
|
|
|
factory StudentBasic.fromJson(Map<String, dynamic> json) {
|
|
return StudentBasic(
|
|
id: SafeConvert.toSafeInt(json['id']),
|
|
name: SafeConvert.toSafeString(json['name']),
|
|
);
|
|
}
|
|
|
|
static StudentBasic? fromNullableJson(dynamic json) {
|
|
final map = SafeConvert.toNullableMap(json);
|
|
if (map == null) return null;
|
|
return StudentBasic.fromJson(map);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() => {'id': id, 'name': name};
|
|
}
|
|
|
|
class StudentProfile {
|
|
final int id;
|
|
final String studentId;
|
|
final String admissionNumber;
|
|
final String? registrationNumber;
|
|
final String? rollNumber;
|
|
final String fullName;
|
|
final String? email;
|
|
final String? mobile;
|
|
final String? phone;
|
|
final String? gender;
|
|
final String? dateOfBirth;
|
|
final String? bloodGroup;
|
|
final String? emergencyContact;
|
|
final String? emergencyPhone;
|
|
final String? street;
|
|
final String? street2;
|
|
final String? city;
|
|
final String? zip;
|
|
final NamedRecord? state;
|
|
final NamedRecord? country;
|
|
final String? guardianName;
|
|
final String? guardianRelation;
|
|
final String? guardianPhone;
|
|
final String? guardianEmail;
|
|
final String status;
|
|
final int profileCompletion;
|
|
final bool hasPhoto;
|
|
|
|
final NamedRecord? campus;
|
|
final NamedRecord? department;
|
|
final NamedRecord? program;
|
|
final NamedRecord? level;
|
|
final NamedRecord? academicYear;
|
|
final NamedRecord? academicTerm;
|
|
final NamedRecord? batch;
|
|
final NamedRecord? semester;
|
|
final NamedRecord? section;
|
|
|
|
final List<String> editableFields;
|
|
final List<String> protectedFields;
|
|
|
|
const StudentProfile({
|
|
required this.id,
|
|
required this.studentId,
|
|
required this.admissionNumber,
|
|
this.registrationNumber,
|
|
this.rollNumber,
|
|
required this.fullName,
|
|
this.email,
|
|
this.mobile,
|
|
this.phone,
|
|
this.gender,
|
|
this.dateOfBirth,
|
|
this.bloodGroup,
|
|
this.emergencyContact,
|
|
this.emergencyPhone,
|
|
this.street,
|
|
this.street2,
|
|
this.city,
|
|
this.zip,
|
|
this.state,
|
|
this.country,
|
|
this.guardianName,
|
|
this.guardianRelation,
|
|
this.guardianPhone,
|
|
this.guardianEmail,
|
|
required this.status,
|
|
this.profileCompletion = 0,
|
|
this.hasPhoto = false,
|
|
this.campus,
|
|
this.department,
|
|
this.program,
|
|
this.level,
|
|
this.academicYear,
|
|
this.academicTerm,
|
|
this.batch,
|
|
this.semester,
|
|
this.section,
|
|
this.editableFields = const [],
|
|
this.protectedFields = const [],
|
|
});
|
|
|
|
factory StudentProfile.fromJson(Map<String, dynamic> json) {
|
|
// If the data is nested under 'profile', unpack it
|
|
final data = json.containsKey('profile') && json['profile'] is Map<String, dynamic>
|
|
? json['profile'] as Map<String, dynamic>
|
|
: json;
|
|
|
|
final guardianMap = SafeConvert.toNullableMap(data['guardian']);
|
|
|
|
final editable = (data['editable_fields'] as List<dynamic>?)
|
|
?.map((e) => e.toString())
|
|
.toList() ??
|
|
const [];
|
|
final protected = (data['protected_fields'] as List<dynamic>?)
|
|
?.map((e) => e.toString())
|
|
.toList() ??
|
|
const [];
|
|
|
|
return StudentProfile(
|
|
id: SafeConvert.toSafeInt(data['id']),
|
|
studentId: SafeConvert.toSafeString(data['student_id']),
|
|
admissionNumber: SafeConvert.toSafeString(data['admission_number']),
|
|
registrationNumber: SafeConvert.toNullableString(data['registration_number']),
|
|
rollNumber: SafeConvert.toNullableString(data['roll_number']),
|
|
fullName: SafeConvert.toSafeString(data['full_name']),
|
|
email: SafeConvert.toNullableString(data['email']),
|
|
mobile: SafeConvert.toNullableString(data['mobile']),
|
|
phone: SafeConvert.toNullableString(data['phone']),
|
|
gender: SafeConvert.toNullableString(data['gender']),
|
|
dateOfBirth: SafeConvert.toNullableString(data['date_of_birth']),
|
|
bloodGroup: SafeConvert.toNullableString(data['blood_group']),
|
|
emergencyContact: SafeConvert.toNullableString(data['emergency_contact']),
|
|
emergencyPhone: SafeConvert.toNullableString(data['emergency_phone']),
|
|
street: SafeConvert.toNullableString(data['street']),
|
|
street2: SafeConvert.toNullableString(data['street2']),
|
|
city: SafeConvert.toNullableString(data['city']),
|
|
zip: SafeConvert.toNullableString(data['zip']),
|
|
state: NamedRecord.fromNullableJson(data['state']),
|
|
country: NamedRecord.fromNullableJson(data['country']),
|
|
guardianName: guardianMap != null ? SafeConvert.toNullableString(guardianMap['name']) : null,
|
|
guardianRelation: guardianMap != null ? SafeConvert.toNullableString(guardianMap['relation']) : null,
|
|
guardianPhone: guardianMap != null ? SafeConvert.toNullableString(guardianMap['phone']) : null,
|
|
guardianEmail: guardianMap != null ? SafeConvert.toNullableString(guardianMap['email']) : null,
|
|
status: SafeConvert.toSafeString(data['status'], 'draft'),
|
|
profileCompletion: SafeConvert.toSafeInt(data['profile_completion']),
|
|
hasPhoto: SafeConvert.toSafeBool(data['has_photo']),
|
|
campus: NamedRecord.fromNullableJson(data['campus']),
|
|
department: NamedRecord.fromNullableJson(data['department']),
|
|
program: NamedRecord.fromNullableJson(data['program']),
|
|
level: NamedRecord.fromNullableJson(data['level']),
|
|
academicYear: NamedRecord.fromNullableJson(data['academic_year']),
|
|
academicTerm: NamedRecord.fromNullableJson(data['academic_term']),
|
|
batch: NamedRecord.fromNullableJson(data['batch']),
|
|
semester: NamedRecord.fromNullableJson(data['semester']),
|
|
section: NamedRecord.fromNullableJson(data['section']),
|
|
editableFields: editable,
|
|
protectedFields: protected,
|
|
);
|
|
}
|
|
}
|
|
|
|
class StudentDocument {
|
|
final int id;
|
|
final String name;
|
|
final String category;
|
|
final String categoryLabel;
|
|
final String? fileName;
|
|
final int fileSize;
|
|
final String? mimeType;
|
|
final String verificationStatus; // 'submitted', 'verified', 'rejected'
|
|
final String uploadDate;
|
|
final String? verificationDate;
|
|
final String? rejectionReason;
|
|
|
|
const StudentDocument({
|
|
required this.id,
|
|
required this.name,
|
|
required this.category,
|
|
required this.categoryLabel,
|
|
this.fileName,
|
|
this.fileSize = 0,
|
|
this.mimeType,
|
|
required this.verificationStatus,
|
|
required this.uploadDate,
|
|
this.verificationDate,
|
|
this.rejectionReason,
|
|
});
|
|
|
|
bool get isVerified => verificationStatus == 'verified';
|
|
bool get isRejected => verificationStatus == 'rejected';
|
|
bool get isSubmitted => verificationStatus == 'submitted';
|
|
|
|
factory StudentDocument.fromJson(Map<String, dynamic> json) {
|
|
return StudentDocument(
|
|
id: SafeConvert.toSafeInt(json['id']),
|
|
name: SafeConvert.toSafeString(json['name']),
|
|
category: SafeConvert.toSafeString(json['category'], 'academic'),
|
|
categoryLabel: SafeConvert.toSafeString(json['category_label'], json['category'] ?? 'Academic'),
|
|
fileName: SafeConvert.toNullableString(json['file_name']),
|
|
fileSize: SafeConvert.toSafeInt(json['file_size']),
|
|
mimeType: SafeConvert.toNullableString(json['mime_type']),
|
|
verificationStatus: SafeConvert.toSafeString(json['verification_status'], 'submitted'),
|
|
uploadDate: SafeConvert.toSafeString(json['upload_date']),
|
|
verificationDate: SafeConvert.toNullableString(json['verification_date']),
|
|
rejectionReason: SafeConvert.toNullableString(json['rejection_reason']),
|
|
);
|
|
}
|
|
}
|
|
|
|
class StudentCertificate {
|
|
final int id;
|
|
final String name;
|
|
final String certificateType;
|
|
final String certificateTypeLabel;
|
|
final String state; // 'draft', 'requested', 'approved', 'issued', 'rejected'
|
|
final String requestDate;
|
|
final String? issueDate;
|
|
final String? expiryDate;
|
|
final String? fileName;
|
|
final String? remarks;
|
|
final String? rejectionReason;
|
|
final bool hasFile;
|
|
|
|
const StudentCertificate({
|
|
required this.id,
|
|
required this.name,
|
|
required this.certificateType,
|
|
required this.certificateTypeLabel,
|
|
required this.state,
|
|
required this.requestDate,
|
|
this.issueDate,
|
|
this.expiryDate,
|
|
this.fileName,
|
|
this.remarks,
|
|
this.rejectionReason,
|
|
this.hasFile = false,
|
|
});
|
|
|
|
bool get isIssued => state == 'issued';
|
|
bool get isApproved => state == 'approved';
|
|
bool get isRequested => state == 'requested';
|
|
bool get isRejected => state == 'rejected';
|
|
|
|
factory StudentCertificate.fromJson(Map<String, dynamic> json) {
|
|
return StudentCertificate(
|
|
id: SafeConvert.toSafeInt(json['id']),
|
|
name: SafeConvert.toSafeString(json['name']),
|
|
certificateType: SafeConvert.toSafeString(json['certificate_type']),
|
|
certificateTypeLabel: SafeConvert.toSafeString(
|
|
json['certificate_type_label'],
|
|
json['certificate_type'] ?? 'Certificate',
|
|
),
|
|
state: SafeConvert.toSafeString(json['state'], 'draft'),
|
|
requestDate: SafeConvert.toSafeString(json['request_date']),
|
|
issueDate: SafeConvert.toNullableString(json['issue_date']),
|
|
expiryDate: SafeConvert.toNullableString(json['expiry_date']),
|
|
fileName: SafeConvert.toNullableString(json['file_name']),
|
|
remarks: SafeConvert.toNullableString(json['remarks']),
|
|
rejectionReason: SafeConvert.toNullableString(json['rejection_reason']),
|
|
hasFile: SafeConvert.toSafeBool(json['has_file']),
|
|
);
|
|
}
|
|
}
|