Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

student enrollment changes added #468

Merged
merged 37 commits into from
Jan 22, 2025
Merged
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e75e1a5
fetch classes api function bug fixed
lahirulakruwan Nov 5, 2024
7c1ef3e
Merge remote-tracking branch 'upstream/main'
lahirulakruwan Nov 5, 2024
7a94f52
Merge pull request #449 from lahirulakruwan/main
YujithIsura Nov 5, 2024
c045325
Toast message added for monthly leave dates picker
lahirulakruwan Nov 6, 2024
53d985c
Merge remote-tracking branch 'upstream/main'
lahirulakruwan Nov 6, 2024
965653e
Merge pull request #451 from lahirulakruwan/main
YujithIsura Nov 6, 2024
5f2239e
lint
YujithIsura Nov 6, 2024
fb086b8
Merge remote-tracking branch 'upstream/main'
YujithIsura Nov 6, 2024
40527f4
Added Monthly payment amount by organization api fetch function
lahirulakruwan Nov 8, 2024
8e8ed09
Merge remote-tracking branch 'upstream/main'
lahirulakruwan Nov 8, 2024
5a3c17b
Merge pull request #453 from lahirulakruwan/main
YujithIsura Nov 8, 2024
64ded91
fixed attendance dashboard class loading issue
YujithIsura Nov 8, 2024
22471db
Merge remote-tracking branch 'upstream/main'
YujithIsura Nov 8, 2024
488a68b
batch selection feture added for bulk attendance marker
YujithIsura Nov 8, 2024
e206e25
Merge pull request #454 from YujithIsura/main
YujithIsura Nov 8, 2024
7cf3e80
Batch select changes added to frontend late attendance report and mon…
lahirulakruwan Nov 21, 2024
ee37a5a
Merge pull request #455 from lahirulakruwan/main
YujithIsura Nov 22, 2024
c585e09
mobile app version updated
YujithIsura Dec 11, 2024
97f611c
student update error fixed in enrollment
YujithIsura Dec 20, 2024
5051319
Merge pull request #458 from YujithIsura/main
YujithIsura Dec 20, 2024
02e66b0
lint
YujithIsura Dec 20, 2024
499ca21
lint
YujithIsura Dec 20, 2024
d75d19e
Merge pull request #460 from YujithIsura/main
YujithIsura Dec 20, 2024
0e961b2
enrollment update and insert bug fixed
YujithIsura Jan 2, 2025
a6ca5db
Merge remote-tracking branch 'upstream/main'
YujithIsura Jan 2, 2025
31a77c6
Merge pull request #462 from YujithIsura/main
YujithIsura Jan 2, 2025
92ff9e0
Student File upload changes added
lahirulakruwan Jan 3, 2025
8bd287b
Merge remote-tracking branch 'upstream/main'
lahirulakruwan Jan 3, 2025
954f0e6
Merge pull request #464 from lahirulakruwan/main
YujithIsura Jan 3, 2025
9ba4ef2
bug fixed in avinya type of student update
YujithIsura Jan 6, 2025
51b708d
student file upload WIP
YujithIsura Jan 6, 2025
f4ef1f1
Merge remote-tracking branch 'upstream/main'
YujithIsura Jan 6, 2025
da38831
Merge pull request #465 from YujithIsura/main
YujithIsura Jan 6, 2025
9e3446f
Class icons added to the icon folder
lahirulakruwan Jan 9, 2025
b2831b5
Merge remote-tracking branch 'upstream/main'
lahirulakruwan Jan 9, 2025
0b4b1ae
Student document upload api changes added
lahirulakruwan Jan 21, 2025
69124a5
Merge pull request #467 from lahirulakruwan/main
YujithIsura Jan 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
student update error fixed in enrollment
YujithIsura committed Dec 20, 2024
commit 97f611ce9d5b92dff6f082aa88904634500f471c
616 changes: 356 additions & 260 deletions campus/frontend/lib/avinya/enrollment/lib/widgets/student_create.dart
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ class _StudentCreateState extends State<StudentCreate> {
List<MainOrganization> organizations = [];
List<AvinyaType> avinyaTypes = [];
List<MainOrganization> classes = [];
int _currentStep = 0; // Track the current step
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
List<City> cityList = [];

@@ -102,221 +103,364 @@ class _StudentCreateState extends State<StudentCreate> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Center(
child: SizedBox(
width: 800,
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// _buildProfileHeader(context),
const SizedBox(height: 20),
_buildSectionTitle(context, 'Student Information'),
_buildEditableField(
'Preferred Name', userPerson.preferred_name, (value) {
userPerson.preferred_name = value;
},
validator: (value) =>
value!.isEmpty ? 'Preferred name is required' : null),
_buildEditableField('Full Name', userPerson.full_name,
(value) {
userPerson.full_name = value;
},
validator: (value) =>
value!.isEmpty ? 'Full name is required' : null),
_buildEditableField('NIC Number', userPerson.nic_no, (value) {
userPerson.nic_no = value;
}, validator: _validateNIC),
_buildDateOfBirthField(context),
_buildSexField(),
const SizedBox(height: 10),
FutureBuilder<List<MainOrganization>>(
future: fetchOrganizationList(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Container(
margin: EdgeInsets.only(top: 10),
child: SpinKitCircle(
color: (Color.fromARGB(255, 74, 161, 70)),
size: 70,
body: Center(
child: SizedBox(
width: 850,
child: Stepper(
type: StepperType.vertical,
currentStep: _currentStep,
onStepContinue: _nextStep,
onStepCancel: _previousStep,
steps: [
// Step 1: Student Information Form
Step(
title: Text('Student Information'),
content: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Center(
child: SizedBox(
width: 800,
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// _buildProfileHeader(context),
const SizedBox(height: 20),
_buildSectionTitle(context, 'Student Information'),
_buildEditableField(
'Preferred Name', userPerson.preferred_name,
(value) {
userPerson.preferred_name = value;
},
validator: (value) => value!.isEmpty
? 'Preferred name is required'
: null),
_buildEditableField(
'Full Name', userPerson.full_name, (value) {
userPerson.full_name = value;
},
validator: (value) => value!.isEmpty
? 'Full name is required'
: null),
_buildEditableField('NIC Number', userPerson.nic_no,
(value) {
userPerson.nic_no = value;
}, validator: _validateNIC),
_buildDateOfBirthField(context),
_buildSexField(),
const SizedBox(height: 10),
FutureBuilder<List<MainOrganization>>(
future: fetchOrganizationList(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Container(
margin: EdgeInsets.only(top: 10),
child: SpinKitCircle(
color:
(Color.fromARGB(255, 74, 161, 70)),
size: 70,
),
);
} else if (snapshot.hasError) {
return const Center(
child: Text('Something went wrong...'),
);
} else if (!snapshot.hasData) {
return const Center(
child: Text('No organizations found'),
);
} else if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
WidgetsBinding.instance
.addPostFrameCallback((_) {
if (!isOrganizationsDataLoaded) {
setState(() {
isOrganizationsDataLoaded = true;
print(
"isorgdataload:${isOrganizationsDataLoaded}");
});
}
});
organizations = snapshot.data!;
return _buildOrganizationField();
}
return SizedBox();
}),
_buildStudentClassField(), // Student Class based on organization.description
const SizedBox(height: 20),
_buildSectionTitle(context, 'Contact Information'),
_buildEditableField(
'Personal Email', userPerson.email, (value) {
userPerson.email = value;
}), // Email format validation

_buildEditableField(
'Phone', userPerson.phone?.toString() ?? '',
(value) {
userPerson.phone = int.tryParse(value);
}, validator: _validatePhone),
_buildEditableField(
'Street Address',
userPerson.mailing_address?.street_address ??
'N/A', (value) {
if (userPerson.mailing_address == null) {
userPerson.mailing_address =
Address(street_address: value);
} else {
userPerson.mailing_address!.street_address =
value;
}
}),
FutureBuilder<List<District>>(
future: fetchDistrictList(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Container(
margin: EdgeInsets.only(top: 10),
child: SpinKitCircle(
color:
(Color.fromARGB(255, 74, 161, 70)),
size: 70,
),
);
} else if (snapshot.hasError) {
return const Center(
child: Text('Something went wrong...'),
);
} else if (!snapshot.hasData) {
return const Center(
child: Text('No districts found'),
);
} else if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
WidgetsBinding.instance
.addPostFrameCallback((_) {
if (!isDistrictsDataLoaded) {
setState(() {
isDistrictsDataLoaded = true;
print(
"isDistrictsDataLoaded:${isDistrictsDataLoaded}");
});
}
});
districts = snapshot.data!;
int? districtId = getDistrictIdByCityId(
selectedCityId, districts);
selectedDistrictId =
districtId ?? selectedDistrictId;
return Column(
children: [
_buildDistrictField(),
_buildCityField(),
],
);
}
return SizedBox();
}),
const SizedBox(height: 20),
_buildSectionTitle(context, 'Digital Information'),
_buildEditableField(
'Digital ID', userPerson.digital_id, (value) {
userPerson.digital_id = value;
}),
FutureBuilder<List<AvinyaType>>(
future: fetchAvinyaTypeList(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Container(
margin: EdgeInsets.only(top: 10),
child: SpinKitCircle(
color:
(Color.fromARGB(255, 74, 161, 70)),
size: 70,
),
);
} else if (snapshot.hasError) {
return const Center(
child: Text('Something went wrong...'),
);
} else if (!snapshot.hasData) {
return const Center(
child: Text('No avinya types found'),
);
} else if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
WidgetsBinding.instance
.addPostFrameCallback((_) {
if (!isAvinyaTypesDataLoaded) {
setState(() {
isAvinyaTypesDataLoaded = true;
print(
"isAvinyaTypesDataLoaded:${isAvinyaTypesDataLoaded}");
});
}
});
avinyaTypes = snapshot.data!;
return _buildAvinyaTypeField();
}
return SizedBox();
}),
const SizedBox(height: 20),
_buildSectionTitle(context, 'Bank Information'),
_buildEditableField(
'Bank Name', userPerson.bank_name, (value) {
userPerson.bank_name = value;
}),
_buildEditableField(
'Bank Branch', userPerson.bank_branch, (value) {
userPerson.bank_branch = value;
}),
_buildEditableField('Bank Account Name',
userPerson.bank_account_name, (value) {
userPerson.bank_account_name = value;
}),
_buildEditableField('Account Number',
userPerson.bank_account_number, (value) {
userPerson.bank_account_number = value;
}),

const SizedBox(height: 20),
_buildSectionTitle(context, 'More Information'),
ExpansionTile(
title: Text(
'Click to expand more information',
style: Theme.of(context).textTheme.subtitle1,
),
children: [
// Guardian Information
_buildSectionTitle(
context, 'Guardian Information'),
_buildEditableField(
'Guardian Name', userPerson.guardian_name,
(value) {
userPerson.guardian_name = value;
},
validator: (value) => value!.isEmpty
? 'Guardian name is required'
: null),
_buildEditableField(
'Guardian Contact Number',
userPerson.guardian_contact_number
?.toString() ??
'', (value) {
userPerson.guardian_contact_number =
int.tryParse(value);
}, validator: _validatePhone),

const SizedBox(height: 20),

// O/L Results Section
_buildSectionTitle(context, 'O/L Results'),
// _buildEditableField('Subject 1', userPerson.ol_subject1,
// (value) {
// userPerson.ol_subject1 = value;
// }),
// _buildEditableField('Subject 2', userPerson.ol_subject2,
// (value) {
// userPerson.ol_subject2 = value;
// }),
// _buildEditableField('Subject 3', userPerson.ol_subject3,
// (value) {
// userPerson.ol_subject3 = value;
// }),
// _buildEditableField(
// 'Other Results', userPerson.ol_other_results,
// (value) {
// userPerson.ol_other_results = value;
// }),

const SizedBox(height: 20),

// Add other expandable sections here if needed
],
),
);
} else if (snapshot.hasError) {
return const Center(
child: Text('Something went wrong...'),
);
} else if (!snapshot.hasData) {
return const Center(
child: Text('No organizations found'),
);
} else if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!isOrganizationsDataLoaded) {
setState(() {
isOrganizationsDataLoaded = true;
print(
"isorgdataload:${isOrganizationsDataLoaded}");
});
}
});
organizations = snapshot.data!;
return _buildOrganizationField();
}
return SizedBox();
}),
_buildStudentClassField(), // Student Class based on organization.description
const SizedBox(height: 20),
_buildSectionTitle(context, 'Contact Information'),
_buildEditableField('Personal Email', userPerson.email,
(value) {
userPerson.email = value;
}), // Email format validation

_buildEditableField(
'Phone', userPerson.phone?.toString() ?? '', (value) {
userPerson.phone = int.tryParse(value);
}, validator: _validatePhone),
_buildEditableField('Street Address',
userPerson.mailing_address?.street_address ?? 'N/A',
(value) {
if (userPerson.mailing_address == null) {
userPerson.mailing_address =
Address(street_address: value);
} else {
userPerson.mailing_address!.street_address = value;
}
}),
FutureBuilder<List<District>>(
future: fetchDistrictList(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Container(
margin: EdgeInsets.only(top: 10),
child: SpinKitCircle(
color: (Color.fromARGB(255, 74, 161, 70)),
size: 70,
),
);
} else if (snapshot.hasError) {
return const Center(
child: Text('Something went wrong...'),
);
} else if (!snapshot.hasData) {
return const Center(
child: Text('No districts found'),
);
} else if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!isDistrictsDataLoaded) {
setState(() {
isDistrictsDataLoaded = true;
print(
"isDistrictsDataLoaded:${isDistrictsDataLoaded}");
});
}
});
districts = snapshot.data!;
int? districtId =
getDistrictIdByCityId(selectedCityId, districts);
selectedDistrictId = districtId ?? selectedDistrictId;
return Column(
children: [
_buildDistrictField(),
_buildCityField(),
],
);
}
return SizedBox();
}),
const SizedBox(height: 20),
_buildSectionTitle(context, 'Digital Information'),
_buildEditableField('Digital ID', userPerson.digital_id,
(value) {
userPerson.digital_id = value;
}),
FutureBuilder<List<AvinyaType>>(
future: fetchAvinyaTypeList(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Container(
margin: EdgeInsets.only(top: 10),
child: SpinKitCircle(
color: (Color.fromARGB(255, 74, 161, 70)),
size: 70,
),
);
} else if (snapshot.hasError) {
return const Center(
child: Text('Something went wrong...'),
);
} else if (!snapshot.hasData) {
return const Center(
child: Text('No avinya types found'),
);
} else if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!isAvinyaTypesDataLoaded) {
setState(() {
isAvinyaTypesDataLoaded = true;
print(
"isAvinyaTypesDataLoaded:${isAvinyaTypesDataLoaded}");
});
}
});
avinyaTypes = snapshot.data!;
return _buildAvinyaTypeField();
}
return SizedBox();
}),
const SizedBox(height: 20),
_buildSectionTitle(context, 'Bank Information'),
_buildEditableField('Bank Name', userPerson.bank_name,
(value) {
userPerson.bank_name = value;
}),
_buildEditableField('Bank Branch', userPerson.bank_branch,
(value) {
userPerson.bank_branch = value;
}),
_buildEditableField(
'Bank Account Name', userPerson.bank_account_name,
(value) {
userPerson.bank_account_name = value;
}),
_buildEditableField(
'Account Number', userPerson.bank_account_number,
(value) {
userPerson.bank_account_number = value;
}),
// const SizedBox(height: 20),
// _buildSectionTitle(context, 'Professional Information'),
// _buildEditableField('Current Job', userPerson.current_job,
// (value) {
// userPerson.current_job = value;
// }),
// _buildEditableTextArea('Comments', userPerson.notes, (value) {
// userPerson.notes = value;
// }),
const SizedBox(height: 40),
_buildSaveButton(isDistrictsDataLoaded,
isOrganizationsDataLoaded, isAvinyaTypesDataLoaded),
],

// const SizedBox(height: 20),
// _buildSectionTitle(context, 'Professional Information'),
// _buildEditableField('Current Job', userPerson.current_job,
// (value) {
// userPerson.current_job = value;
// }),
// _buildEditableTextArea('Comments', userPerson.notes, (value) {
// userPerson.notes = value;
// }),
const SizedBox(height: 40),
_buildSaveButton(
isDistrictsDataLoaded,
isOrganizationsDataLoaded,
isAvinyaTypesDataLoaded),
],
),
),
),
),
),
isActive: _currentStep >= 0,
),
),
// Step 2: File Upload
Step(
title: Text('Upload Files'),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle(context, 'File Upload'),
_buildFileUploadWidget('Upload Profile Photo'),
_buildFileUploadWidget('Upload NIC Copy'),
_buildFileUploadWidget('Upload O/L Certificate'),
],
),
isActive: _currentStep >= 1,
),
]),
),
));
}

// Navigate to the next step
void _nextStep() {
if (_currentStep == 0) {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
setState(() {
_currentStep += 1;
});
}
} else if (_currentStep < 1) {
setState(() {
_currentStep += 1;
});
}
}

// Navigate to the previous step
void _previousStep() {
if (_currentStep > 0) {
setState(() {
_currentStep -= 1;
});
}
}

// Mock function for file upload widget
Widget _buildFileUploadWidget(String label) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
children: [
ElevatedButton(
onPressed: () {
// Logic to handle file upload
},
child: Text('Upload $label'),
),
),
],
),
);
}
@@ -397,54 +541,6 @@ class _StudentCreateState extends State<StudentCreate> {
);
}

Widget _buildEditableTextArea(
String label, String? initialValue, Function(String) onSave,
{int minLines = 1, int maxLines = 5}) {
// Set maxLines to a desired value for textarea
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
children: [
Expanded(
flex: 4,
child: Text(
label,
style: Theme.of(context).textTheme.bodyText1,
),
),
Expanded(
flex: 6,
child: TextFormField(
initialValue: initialValue ?? '',
decoration: InputDecoration(
contentPadding:
const EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0),
border: OutlineInputBorder(),
),
onSaved: (value) => onSave(value!),
minLines: minLines, // Minimum lines to display
maxLines: maxLines, // Maximum lines to display
maxLength: 1000, // Maximum character limit
buildCounter: (BuildContext context,
{required int currentLength,
required bool isFocused,
required int? maxLength}) {
return Text(
'$currentLength/${maxLength ?? 1000}', // Display character count
style: TextStyle(
color: currentLength > (maxLength ?? 1000)
? Colors.red
: null, // Change color if limit exceeded
),
);
},
),
),
],
),
);
}

Widget _buildSexField() {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
158 changes: 115 additions & 43 deletions campus/frontend/lib/avinya/enrollment/lib/widgets/student_update.dart
Original file line number Diff line number Diff line change
@@ -41,49 +41,101 @@ class _StudentUpdateState extends State<StudentUpdate> {
await fetchAvinyaTypeList();
}

Future<void> getUserPerson() async {
Person user = await fetchPerson(widget.id);
classes = await fetchClasses(
(user.organization?.parent_organizations?.isNotEmpty ?? false)
? user.organization?.parent_organizations?.first.id
: null);
// Future<void> getUserPerson() async {
// Person user = await fetchPerson(widget.id);
// classes = await fetchClasses(
// (user.organization?.parent_organizations?.isNotEmpty ?? false)
// ? user.organization?.parent_organizations?.first.id
// : null);

// setState(() {
// classes = classes;
// userPerson = user;
// selectedSex = userPerson.sex;
// userPerson.avinya_type_id = user.avinya_type_id;
// selectedDistrictId = user.mailing_address?.city?.district!.id;
// // Safely assign city and organization IDs with fallbacks
// selectedCityId = userPerson.mailing_address?.city?.id ??
// 0; // Default to 0 or another fallback value
// if (selectedDistrictId != null) {
// _loadCities(selectedDistrictId, selectedCityId);
// }

setState(() {
classes = classes;
userPerson = user;
selectedSex = userPerson.sex;
userPerson.avinya_type_id = user.avinya_type_id;
selectedDistrictId = user.mailing_address?.city?.district!.id;
// Safely assign city and organization IDs with fallbacks
selectedCityId = userPerson.mailing_address?.city?.id ??
0; // Default to 0 or another fallback value
if (selectedDistrictId != null) {
_loadCities(selectedDistrictId, selectedCityId);
// selectedOrgId =
// userPerson.organization?.id ?? 0; // Similarly handle organization ID
// selectedClassId = userPerson.organization?.id ??
// 0; // Ensure organization ID is used for class as well

// // Handling date of birth
// String? dob = userPerson.date_of_birth;
// print("Date of Birth String: $dob");

// // Safely try parsing the date of birth
// if (dob == null || dob.isEmpty) {
// selectedDateOfBirth = DateTime.now(); // Default if dob is null or empty
// } else {
// try {
// selectedDateOfBirth =
// DateTime.parse(dob); // Use DateTime.parse directly
// } catch (e) {
// print('Error parsing date: $e');
// selectedDateOfBirth =
// DateTime.now(); // Fallback to now if parsing fails
// }
// }
// });
// }
Future<void> getUserPerson() async {
try {
Person user = await fetchPerson(widget.id);

// Safely check if parent_organizations exist and are not empty
final parentOrganizationId =
(user.organization?.parent_organizations?.isNotEmpty ?? false)
? user.organization?.parent_organizations?.first.id
: null;

// Fetch classes with a fallback to an empty list if null
if (parentOrganizationId != null) {
classes = await fetchClasses(parentOrganizationId);
} else {
classes = [];
}

selectedOrgId =
userPerson.organization?.id ?? 0; // Similarly handle organization ID
selectedClassId = userPerson.organization?.id ??
0; // Ensure organization ID is used for class as well

// Handling date of birth
String? dob = userPerson.date_of_birth;
print("Date of Birth String: $dob");
setState(() {
userPerson = user;
selectedSex = userPerson.sex;
userPerson.avinya_type_id = user.avinya_type_id;

// Safely assign district, city, and organization IDs with fallbacks
selectedDistrictId = user.mailing_address?.city?.district?.id;
selectedCityId = userPerson.mailing_address?.city?.id ?? 0;
if (selectedDistrictId != null) {
_loadCities(selectedDistrictId, selectedCityId);
}

// Safely try parsing the date of birth
if (dob == null || dob.isEmpty) {
selectedDateOfBirth = DateTime.now(); // Default if dob is null or empty
} else {
try {
selectedDateOfBirth =
DateTime.parse(dob); // Use DateTime.parse directly
} catch (e) {
print('Error parsing date: $e');
selectedDateOfBirth =
DateTime.now(); // Fallback to now if parsing fails
selectedOrgId = userPerson.organization?.id ?? 0;
selectedClassId = classes.isNotEmpty ? classes.first.id : 0;

// Handling date of birth safely
String? dob = userPerson.date_of_birth;
print("Date of Birth String: $dob");

if (dob == null || dob.isEmpty) {
selectedDateOfBirth = DateTime.now();
} else {
try {
selectedDateOfBirth = DateTime.parse(dob);
} catch (e) {
print('Error parsing date: $e');
selectedDateOfBirth = DateTime.now();
}
}
}
});
});
} catch (e) {
print('Error fetching user data: $e');
// Optionally handle the error further, e.g., show a dialog or fallback UI
}
}

Future<List<District>> fetchDistrictList() async {
@@ -101,7 +153,8 @@ class _StudentUpdateState extends State<StudentUpdate> {
// }
// }
Future<List<MainOrganization>> fetchOrganizationList() async {
return await fetchOrganizations();
final result = await fetchOrganizations();
return result ?? []; // Fallback to an empty list
}

// Future<void> fetchOrganizationList() async {
@@ -199,7 +252,8 @@ class _StudentUpdateState extends State<StudentUpdate> {
);
} else if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
snapshot.hasData &&
snapshot.data!.isNotEmpty) {
WidgetsBinding.instance
.addPostFrameCallback((_) {
if (!isOrganizationsDataLoaded) {
@@ -212,8 +266,9 @@ class _StudentUpdateState extends State<StudentUpdate> {
});
organizations = snapshot.data!;
return _buildOrganizationField();
} else {
return SizedBox();
}
return SizedBox();
}),
// _buildOrganizationField(),
_buildStudentClassField(), // Student Class based on organization.description
@@ -621,6 +676,24 @@ class _StudentUpdateState extends State<StudentUpdate> {
}

Widget _buildOrganizationField() {
if (organizations.isEmpty) {
return const Center(
child: Text('No organizations available to display'),
);
}

final parentOrganizationId =
(userPerson.organization?.parent_organizations != null &&
userPerson.organization!.parent_organizations!.isNotEmpty)
? userPerson.organization!.parent_organizations!.first.id
: 0;
// Ensure parentOrganizationId is in the organizations list or set it to null
final validParentOrganizationId = organizations.any((org) =>
org.id == parentOrganizationId &&
(org.avinya_type?.id == 105 || org.avinya_type?.id == 86))
? parentOrganizationId
: null;

return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
@@ -635,8 +708,7 @@ class _StudentUpdateState extends State<StudentUpdate> {
Expanded(
flex: 6,
child: DropdownButtonFormField<int>(
value:
userPerson.organization?.parent_organizations?.first.id ?? 0,
value: validParentOrganizationId,
items: organizations
.where((org) =>
org.avinya_type?.id == 105 ||