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

Add planner #178

Draft
wants to merge 41 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
e10949b
feat: add planner tab
RGLie May 1, 2024
e8f3663
feat: add planner block colors
RGLie May 1, 2024
d227acb
feat: add planner block colors
RGLie May 1, 2024
03be72d
feat: add planner page
RGLie May 1, 2024
1627e9e
feat: add planner table
RGLie May 1, 2024
c8c0fd0
feat: add planner statistic layout
RGLie May 1, 2024
ad3caf3
chore: add planner color
RGLie May 24, 2024
be2503c
chore: add planner api url
RGLie May 24, 2024
fd0d027
add: planner model change notifier
RGLie May 24, 2024
1c56860
feat: change planner design
RGLie May 24, 2024
cde9cbf
remove unused file
RGLie May 24, 2024
7710481
chore: delete unused import
RGLie May 24, 2024
9c30dfa
feat: add tabs to select planner
RGLie May 24, 2024
72a312b
feat: add planner model
RGLie May 24, 2024
6895ef0
feat: add planner course model
RGLie May 24, 2024
38aae85
feat: add planner provider model
RGLie May 24, 2024
361d38c
feat: add planner preview block
RGLie May 24, 2024
7ba7ef1
feat: add planner semester select tab
RGLie May 24, 2024
d41cbca
feat: add planner lecture view
RGLie May 24, 2024
1322b57
bug: fix format
RGLie May 24, 2024
eb9814f
g11n: add translations for planner dialog
RGLie May 24, 2024
1c10a06
feat: add planner delete dialog
RGLie May 24, 2024
cf48ba4
feat: add planner delete
RGLie May 24, 2024
df94a4d
feat: add planner course detail page
RGLie May 25, 2024
ea7cb5f
feat: add course detail page navigator
RGLie May 25, 2024
94718e7
feat: change planner model lecture structure
RGLie May 25, 2024
a0787c6
feat: add planner track url
RGLie May 25, 2024
61bb6be
feat: add track provider model
RGLie May 25, 2024
ce7d4da
chore: change max height
RGLie May 25, 2024
4dbed9a
feat: add planner update url
RGLie May 25, 2024
22bc997
feat: change track model provider
RGLie May 25, 2024
d6f04ab
feat: add lecture exclude button
RGLie May 25, 2024
83d37de
chore: remove unused model
RGLie May 25, 2024
82b7bec
feat: add planner update and add
RGLie May 25, 2024
b580703
feat: add planner track model
RGLie May 25, 2024
d4a0eb4
feat: change lecture calculation
RGLie May 25, 2024
496e9ec
bug: fix release mode widget error
RGLie May 26, 2024
2c1a39f
bug: fix format
RGLie May 26, 2024
36237af
chore: remove unused import
RGLie May 26, 2024
dc70fb3
bug: fix format
RGLie May 26, 2024
bbceaee
feat: hide planner select tab when loading
RGLie May 26, 2024
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
feat: add planner provider model
  • Loading branch information
RGLie committed May 24, 2024
commit 38aae85b97a68b3a59db072c7f5697d145ab76e9
385 changes: 385 additions & 0 deletions lib/providers/planner_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,385 @@
import 'dart:async';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:otlplus/constants/url.dart';
import 'package:otlplus/dio_provider.dart';
import 'package:otlplus/models/department.dart';
import 'package:otlplus/models/lecture.dart';
import 'package:otlplus/models/planner.dart';
import 'package:otlplus/models/semester.dart';
import 'package:otlplus/models/user.dart';
import 'package:otlplus/utils/export_file.dart';

class PlannerModel extends ChangeNotifier {
late User _user = User(
id: 0,
email: "email",
studentId: "studentId",
firstName: "firstName",
lastName: "lastName",
majors: [],
departments: [],
myTimetableLectures: [],
reviewWritableLectures: [],
reviews: []);
User get user => _user;

late List<Planner> _planners = [
Planner(
id: 0,
start_year: 0,
end_year: 0,
arrange_order: 0,
general_track: GeneralTrack(),
major_track: MajorTrack(department: Department(id: 0, name: "", nameEn: "", code: "")),
additional_tracks: [],
taken_items: [],
future_items: [],
arbitrary_items: [],
),
];

Planner myPlanner = Planner(
id: 0,
start_year: 0,
end_year: 0,
arrange_order: 0,
general_track: GeneralTrack(),
major_track: MajorTrack(department: Department(id: 0, name: "", nameEn: "", code: "")),
additional_tracks: [],
taken_items: [],
future_items: [],
arbitrary_items: [],
);

List<Planner> get planners => _planners;

// late int _selectedSemesterIndex;
// Semester get selectedSemester => _semesters[_selectedSemesterIndex];
//
// late List<Planner> _timetables;
// List<Planner> get timetables => _timetables;
//
// Lecture? _tempLecture;
// Lecture? get tempLecture => _tempLecture;

// void setTempLecture(Lecture? lecture) {
// _tempLecture = lecture;
// notifyListeners();
// }

int _selectedPlannerIndex = 0;
int get selectedIndex => _selectedPlannerIndex;

String _selectedPlannerSemesterKey = "";
String get selectedSemesterKey => _selectedPlannerSemesterKey;

// Planner get currentTimetable => _timetables[_selectedTimetableIndex];
//
// int _selectedModeIndex = 0;
// int get selectedMode => _selectedModeIndex;

bool _isLoaded = false;
bool get isLoaded => _isLoaded;

Map _lectures = {};
Map get lectures => _lectures;

Map _lectures_excluded = {};
Map get lectures_excluded => _lectures_excluded;

int _taken_lectures = 0;
int get taken_lectures => _taken_lectures;

int _taken_au = 0;
int get taken_au => _taken_au;

Map _category_map = {
"기초필수": 0,
"기초선택": 0,
"전공필수": 0,
"전공선택": 0,
"교양필수": 0,
"인문사회선택": 0,
"자유선택": 0,
"졸업연구": 0,
"개별연구": 0,
"기타": 0, //논문연구, 선택(석/박사), 세미나
};
Map get category_map => _category_map;

Map _category_map_required = {
"기초필수": 0,
"기초선택": 0,
"전공필수": 0,
"전공선택": 0,
"교양필수": 0,
"인문사회선택": 0,
"자유선택": 0,
"졸업연구": 0,
"개별연구": 0,
"기타": 0, //논문연구, 선택(석/박사), 세미나
};
Map get category_map_required => _category_map_required;

PlannerModel({bool forTest = false}) {
if (forTest) {
_user = User(
id: 0,
email: "email",
studentId: "studentId",
firstName: "firstName",
lastName: "lastName",
majors: [],
departments: [],
myTimetableLectures: [],
reviewWritableLectures: [],
reviews: []);
_planners = [
Planner(
id: 0,
start_year: 0,
end_year: 0,
arrange_order: 0,
general_track: GeneralTrack(),
major_track: MajorTrack(department: Department(id: 0, name: "", nameEn: "", code: "")),
additional_tracks: [],
taken_items: [],
future_items: [],
arbitrary_items: [],
),
];
}
}

void initializeLectures(){
_lectures = {};
_lectures_excluded = {};
_taken_lectures = 0;
_taken_au = 0;
_selectedPlannerSemesterKey = "";
_category_map = {
"기초필수": 0,
"기초선택": 0,
"전공필수": 0,
"전공선택": 0,
"교양필수": 0,
"인문사회선택": 0,
"자유선택": 0,
"졸업연구": 0,
"개별연구": 0,
"기타": 0, //논문연구, 선택(석/박사), 세미나
};
_category_map_required = {
"기초필수": 0,
"기초선택": 0,
"전공필수": 0,
"전공선택": 0,
"교양필수": 0,
"인문사회선택": 0,
"자유선택": 0,
"졸업연구": 0,
"개별연구": 0,
"기타": 0, //논문연구, 선택(석/박사), 세미나
};
}
//
void loadPlanner({required User user}) {
_user = user;
_selectedPlannerIndex = 0;

notifyListeners();
_loadPlanner();
// setLectures();
// notifyListeners();
}

void selectPlanner(int index){
_selectedPlannerIndex = index;
setLectures();
notifyListeners();
}

void setPLannerSemester(String index){
_selectedPlannerSemesterKey = index;
notifyListeners();
}

void setLectures(){
initializeLectures();


_category_map_required["기초필수"] = _planners[_selectedPlannerIndex].general_track.basic_required;
_category_map_required["기초선택"] = _planners[_selectedPlannerIndex].general_track.basic_elective;
_category_map_required["졸업연구"] = _planners[_selectedPlannerIndex].general_track.thesis_study;
_category_map_required["인문사회선택"] = _planners[_selectedPlannerIndex].general_track.humanities;
_category_map_required["교양필수"] = _planners[_selectedPlannerIndex].general_track.general_required_credit
+ _planners[_selectedPlannerIndex].general_track.general_required_au; //교양필수 7학점 + 8AU
_category_map_required["전공필수"] = _planners[_selectedPlannerIndex].major_track.major_required;
_category_map_required["전공선택"] = _planners[_selectedPlannerIndex].major_track.major_elective;

for(int i = 0; i < _planners[_selectedPlannerIndex].additional_tracks.length; i++){
_category_map_required["전공필수"] += _planners[_selectedPlannerIndex].additional_tracks[i].major_required;
_category_map_required["전공선택"] += _planners[_selectedPlannerIndex].additional_tracks[i].major_elective;
}





for(int i=0; i<_planners[_selectedPlannerIndex].taken_items.length; i++){
if(!_planners[_selectedPlannerIndex].taken_items[i].is_excluded){
if(_category_map.containsKey(_planners[_selectedPlannerIndex].taken_items[i].course.type.split('(')[0])){
_category_map[_planners[_selectedPlannerIndex].taken_items[i].course.type.split('(')[0]] += _planners[_selectedPlannerIndex].taken_items[i].course.credit;
}

_taken_lectures += _planners[_selectedPlannerIndex].taken_items[i].course.credit;
_taken_au += _planners[_selectedPlannerIndex].taken_items[i].course.credit_au;

String year_semester = _planners[_selectedPlannerIndex].taken_items[i].lecture.year.toString()+' '
+_planners[_selectedPlannerIndex].taken_items[i].lecture.semester.toString();
if(_lectures.containsKey(year_semester)){
_lectures[year_semester].add(_planners[_selectedPlannerIndex].taken_items[i].course);
}
else{
_lectures[year_semester] = [_planners[_selectedPlannerIndex].taken_items[i].course];
}
}
else{
String year_semester = _planners[_selectedPlannerIndex].taken_items[i].lecture.year.toString()+' '
+_planners[_selectedPlannerIndex].taken_items[i].lecture.semester.toString();

if(_lectures_excluded.containsKey(year_semester)){
_lectures_excluded[year_semester].add(_planners[_selectedPlannerIndex].taken_items[i].course);
}
else{
_lectures_excluded[year_semester] = [_planners[_selectedPlannerIndex].taken_items[i].course];
}
}
}

for(int i=0; i<_planners[_selectedPlannerIndex].future_items.length; i++){
if(!_planners[_selectedPlannerIndex].future_items[i].is_excluded){
if(_category_map.containsKey(_planners[_selectedPlannerIndex].future_items[i].course.type)){
_category_map[_planners[_selectedPlannerIndex].future_items[i].course.type] += _planners[_selectedPlannerIndex].future_items[i].course.credit;
}

_taken_lectures += _planners[_selectedPlannerIndex].future_items[i].course.credit;
_taken_au += _planners[_selectedPlannerIndex].future_items[i].course.credit_au;

String year_semester = _planners[_selectedPlannerIndex].future_items[i].year.toString()+' '
+_planners[_selectedPlannerIndex].future_items[i].semester.toString();

if(_lectures.containsKey(year_semester)){
_lectures[year_semester].add(_planners[_selectedPlannerIndex].future_items[i].course);
}
else{
_lectures[year_semester] = [_planners[_selectedPlannerIndex].future_items[i].course];
}

}
else{
String year_semester = _planners[_selectedPlannerIndex].future_items[i].year.toString()+' '
+_planners[_selectedPlannerIndex].future_items[i].semester.toString();

if(_lectures_excluded.containsKey(year_semester)){
_lectures_excluded[year_semester].add(_planners[_selectedPlannerIndex].future_items[i].course);
}
else{
_lectures_excluded[year_semester] = [_planners[_selectedPlannerIndex].future_items[i].course];
}
}
}
}
//
// get canGoPreviousSemester => _selectedSemesterIndex > 0;

// bool goPreviousSemester() {
// if (canGoPreviousSemester) {
// _selectedSemesterIndex--;
// notifyListeners();
// _loadPlanner();
// return true;
// }
// return false;
// }
//
// get canGoNextSemester => _selectedSemesterIndex < _semesters.length - 1;

// bool goNextSemester() {
// if (canGoNextSemester) {
// _selectedSemesterIndex++;
// notifyListeners();
// _loadPlanner();
// return true;
// }
// return false;
// }
//
// void setIndex(int index) {
// _selectedTimetableIndex = index;
// notifyListeners();
// }
//
// void setMode(int index) {
// _selectedModeIndex = index;
// notifyListeners();
// }

Future<bool> _loadPlanner() async {
try {
final response = await DioProvider().dio.get(
API_PLANNER_URL.replaceFirst("{user_id}", _user.id.toString()),
);

List<dynamic> rawPlanners = response.data as List;

if (rawPlanners.isEmpty) {
_selectedPlannerIndex = 0;
_planners = [myPlanner];
// await createTimetable();
await _loadPlanner();
return true;
}

_planners = rawPlanners
.map((planner) => Planner.fromJson(planner))
.toList();


_planners.insert(0, myPlanner);
_selectedPlannerIndex = _planners.length >= 2 ? 1 : 0;
_isLoaded = true;
setLectures();
notifyListeners();
return true;
} catch (exception) {
print(exception);
}
return false;
}

// Future<bool> createTimetable({List<Lecture>? lectures}) async {
// try {
// final response = await DioProvider().dio.post(
// API_PLANNER_URL.replaceFirst("{user_id}", user.id.toString()),
// data: {
// "year": selectedSemester.year,
// "semester": selectedSemester.semester,
// "lectures": (lectures == null)
// ? []
// : lectures.map((lecture) => lecture.id).toList(),
// });
// final timetable = Planner.fromJson(response.data);
// _timetables.add(timetable);
// _selectedTimetableIndex = _timetables.length - 1;
// notifyListeners();
// return true;
// } catch (exception) {
// print(exception);
// }
// return false;
// }

}