From 71e18e4b6d0fc93d562aa4f8e21cca20c353c154 Mon Sep 17 00:00:00 2001 From: Septian Jauhariansyah Date: Tue, 23 Sep 2025 09:48:43 +0700 Subject: [PATCH 1/4] Initial comit for this branch --- pubspec.lock | 86 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 27 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index e3261f8..d47932b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" chewie: dependency: "direct main" description: @@ -61,18 +61,18 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.19.1" convert: dependency: transitive description: @@ -117,10 +117,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" ffi: dependency: transitive description: @@ -224,6 +224,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.7" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" lints: dependency: transitive description: @@ -244,26 +268,26 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.17" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.16.0" nested: dependency: transitive description: @@ -300,10 +324,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.1" path_parsing: dependency: transitive description: @@ -460,7 +484,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -473,18 +497,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.4" string_scanner: dependency: transitive description: @@ -505,10 +529,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.7.6" typed_data: dependency: transitive description: @@ -545,10 +569,10 @@ packages: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" video_player: dependency: "direct main" description: @@ -589,6 +613,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.17" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + url: "https://pub.dev" + source: hosted + version: "15.0.2" wakelock_plus: dependency: transitive description: @@ -630,5 +662,5 @@ packages: source: hosted version: "6.3.0" sdks: - dart: ">=3.0.6 <4.0.0" - flutter: ">=3.10.0" + dart: ">=3.8.0-0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" From de19d06eab687f4d1f8cbccaa683d88e38577aea Mon Sep 17 00:00:00 2001 From: Septian Jauhariansyah Date: Wed, 24 Sep 2025 21:46:38 +0700 Subject: [PATCH 2/4] add role-based dashboard redirection and placeholder screens --- assets/mock/fake_auth.json | 5 +++ lib/controllers/auth_controller.dart | 40 ++++++++++++++++++++++ lib/helpers/request_helpers.dart | 6 ++-- lib/main.dart | 37 +++++++++++++------- lib/models/category_model.dart | 4 +-- lib/models/user_model.dart | 14 +++++++- lib/routes/route_destinations.dart | 6 ++-- lib/routes/route_names.dart | 2 +- lib/utils/app_urls.dart | 2 +- lib/views/Admin/admin_dashboard.drt | 13 +++++++ lib/views/HomeScreen/home_screen.dart | 4 +-- lib/views/Lecturer/lecturer_dashboard.dart | 13 +++++++ lib/views/Student/student_dashboard.dart | 13 +++++++ pubspec.yaml | 1 + 14 files changed, 135 insertions(+), 25 deletions(-) create mode 100644 assets/mock/fake_auth.json create mode 100644 lib/controllers/auth_controller.dart create mode 100644 lib/views/Admin/admin_dashboard.drt create mode 100644 lib/views/Lecturer/lecturer_dashboard.dart create mode 100644 lib/views/Student/student_dashboard.dart diff --git a/assets/mock/fake_auth.json b/assets/mock/fake_auth.json new file mode 100644 index 0000000..95f0dbd --- /dev/null +++ b/assets/mock/fake_auth.json @@ -0,0 +1,5 @@ +{ + "username": "john_doe", + "role": "student", + "token": "abc123xyz" +} diff --git a/lib/controllers/auth_controller.dart b/lib/controllers/auth_controller.dart new file mode 100644 index 0000000..b8f750d --- /dev/null +++ b/lib/controllers/auth_controller.dart @@ -0,0 +1,40 @@ +import 'dart:convert'; +import 'package:get/get.dart'; +import 'package:interactive_cares_lms/models/user_model.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class AuthController extends GetxController { + var currentUser = Rxn(); + + Future login(String username, String password) async { + // Fake API call (replace with real HTTP later) + final fakeApiResponse = ''' + { + "username": "$username", + "role": "${username == 'admin' ? 'admin' : username == 'lecturer' ? 'lecturer' : 'student'}", + "token": "mockToken123" + } + '''; + + final data = json.decode(fakeApiResponse); + currentUser.value = UserModel.fromJson(data); + + // Save user data + SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('user', json.encode(data)); + } + + Future loadUser() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + if (prefs.containsKey('user')) { + final data = json.decode(prefs.getString('user')!); + currentUser.value = UserModel.fromJson(data); + } + } + + Future logout() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.remove('user'); + currentUser.value = null; + } +} diff --git a/lib/helpers/request_helpers.dart b/lib/helpers/request_helpers.dart index 870a5e2..903c0bf 100644 --- a/lib/helpers/request_helpers.dart +++ b/lib/helpers/request_helpers.dart @@ -1,9 +1,9 @@ class RequestHelpers { - static Map header () { + static Map header() { Map header = { - 'Accept' : 'application/json', + 'Accept': 'application/json', }; return header; } -} \ No newline at end of file +} diff --git a/lib/main.dart b/lib/main.dart index fb78fb8..c8f48cc 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,13 +1,21 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:interactive_cares_lms/controllers/auth_controller.dart'; import 'package:interactive_cares_lms/bindings/all_bindings.dart'; import 'package:interactive_cares_lms/routes/route_destinations.dart'; import 'package:interactive_cares_lms/routes/route_names.dart'; import 'package:interactive_cares_lms/utils/colors.dart'; import 'package:interactive_cares_lms/utils/config.dart'; +import 'package:interactive_cares_lms/views/Admin/admin_dashboard.dart'; +import 'package:interactive_cares_lms/views/Lecturer/lecturer_dashboard.dart'; +import 'package:interactive_cares_lms/views/Student/student_dashboard.dart'; +import 'package:interactive_cares_lms/views/Authentication/LoginScreen/login_screen.dart'; -void main() { + +void main() async { WidgetsFlutterBinding.ensureInitialized(); + final authController = Get.put(AuthController()); + await authController.loadUser(); // ✅ allowed now AllBindings().dependencies(); runApp(const MyApp()); } @@ -18,15 +26,18 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return GetMaterialApp( - debugShowCheckedModeBanner: false, - title: AppConfig.appName, - theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: AppColors.primary), - useMaterial3: true, - scaffoldBackgroundColor: AppColors.background, - ), - getPages: Routes.destination, - initialRoute: RouteNames.initial, - ); - } -} + initialBinding: AllBindings(), + home: Obx(() { + final user = Get.find().currentUser.value; + if (user == null) { + return LoginPage(); + } else if (user.role == 'admin') { + return AdminDashboard(); + } else if (user.role == 'lecturer') { + return LecturerDashboard(); + } else { + return StudentDashboard(); + } + }), +); + diff --git a/lib/models/category_model.dart b/lib/models/category_model.dart index a51ba9b..5cf263e 100644 --- a/lib/models/category_model.dart +++ b/lib/models/category_model.dart @@ -4,7 +4,7 @@ class CategoryModel { String title; String icon; - CategoryModel ({required this.title, required this.icon}); + CategoryModel({required this.title, required this.icon}); } List getCategories = [ @@ -13,4 +13,4 @@ List getCategories = [ CategoryModel(title: 'Editing', icon: ImageManager.video), CategoryModel(title: 'Development', icon: ImageManager.personalDevelopment), CategoryModel(title: 'Math', icon: ImageManager.math), -]; \ No newline at end of file +]; diff --git a/lib/models/user_model.dart b/lib/models/user_model.dart index 24e154d..a79f2ae 100644 --- a/lib/models/user_model.dart +++ b/lib/models/user_model.dart @@ -3,20 +3,32 @@ class UserModel { String? fullName; String? email; String? password; + String? role; // UserModel({ this.username, this.email, this.password, this.fullName, + this.role, }); Map toJson() { return { - 'full_name' : fullName, + 'full_name': fullName, 'username': username, 'email': email, 'password': password, + 'role': role, }; } + + factory UserModel.fromJson(Map json) { + return UserModel( + username: json['username'], + fullName: json['full_name'], + email: json['email'], + role: json['role'], + ); + } } diff --git a/lib/routes/route_destinations.dart b/lib/routes/route_destinations.dart index 03b54c1..b5e6cfd 100644 --- a/lib/routes/route_destinations.dart +++ b/lib/routes/route_destinations.dart @@ -19,6 +19,8 @@ class Routes { GetPage(name: RouteNames.home, page: () => const BottomBarView()), GetPage(name: RouteNames.courseLearn, page: () => const LearningScreen()), GetPage(name: RouteNames.lesson, page: () => const LessonScreen()), - GetPage(name: RouteNames.bookmarkPlayer, page: () => const BookmarkPlayerScreen()), + GetPage( + name: RouteNames.bookmarkPlayer, + page: () => const BookmarkPlayerScreen()), ]; -} \ No newline at end of file +} diff --git a/lib/routes/route_names.dart b/lib/routes/route_names.dart index 764028d..adfbed1 100644 --- a/lib/routes/route_names.dart +++ b/lib/routes/route_names.dart @@ -8,4 +8,4 @@ class RouteNames { static const String courseLearn = '/courseLearn'; static const String lesson = '/lesson'; static const String bookmarkPlayer = '/bookmark-player'; -} \ No newline at end of file +} diff --git a/lib/utils/app_urls.dart b/lib/utils/app_urls.dart index bfe6b95..bbaf20d 100644 --- a/lib/utils/app_urls.dart +++ b/lib/utils/app_urls.dart @@ -5,4 +5,4 @@ class AppUrls { static const String apiUrl = '${AppConfig.baseUrl}/api/$apiVersion'; static Uri login = Uri.parse('$apiUrl/login'); static Uri register = Uri.parse('$apiUrl/register'); -} \ No newline at end of file +} diff --git a/lib/views/Admin/admin_dashboard.drt b/lib/views/Admin/admin_dashboard.drt new file mode 100644 index 0000000..48fee57 --- /dev/null +++ b/lib/views/Admin/admin_dashboard.drt @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class AdminDashboard extends StatelessWidget { + const AdminDashboard({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text("Admin Dashboard")), + body: const Center(child: Text("Welcome Admin")), + ); + } +} diff --git a/lib/views/HomeScreen/home_screen.dart b/lib/views/HomeScreen/home_screen.dart index 6b9c4fd..7b21da1 100644 --- a/lib/views/HomeScreen/home_screen.dart +++ b/lib/views/HomeScreen/home_screen.dart @@ -32,8 +32,8 @@ class HomeScreen extends StatelessWidget { children: [ HomeAppBar(), Padding( - padding: EdgeInsets.symmetric( - horizontal: 10, vertical: 15), + padding: + EdgeInsets.symmetric(horizontal: 10, vertical: 15), child: Column( children: [ SliderSection(), diff --git a/lib/views/Lecturer/lecturer_dashboard.dart b/lib/views/Lecturer/lecturer_dashboard.dart new file mode 100644 index 0000000..eabff83 --- /dev/null +++ b/lib/views/Lecturer/lecturer_dashboard.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class LecturerDashboard extends StatelessWidget { + const LecturerDashboard({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text("Lecturer Dashboard")), + body: const Center(child: Text("Welcome Lecturer")), + ); + } +} diff --git a/lib/views/Student/student_dashboard.dart b/lib/views/Student/student_dashboard.dart new file mode 100644 index 0000000..ac07463 --- /dev/null +++ b/lib/views/Student/student_dashboard.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class StudentDashboard extends StatelessWidget { + const StudentDashboard({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text("Student Dashboard")), + body: const Center(child: Text("Welcome Student")), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 60dd123..1ee25b1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ flutter: uses-material-design: true assets: + - assets/mock/ - assets/ - assets/images/ - assets/svg/ From 1ab8b7bf6334fa96286592467c9a7e0d11ae64f8 Mon Sep 17 00:00:00 2001 From: Septian Jauhariansyah Date: Wed, 24 Sep 2025 21:48:46 +0700 Subject: [PATCH 3/4] fixing typo --- lib/views/Admin/{admin_dashboard.drt => admin_dashboard.dart} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/views/Admin/{admin_dashboard.drt => admin_dashboard.dart} (100%) diff --git a/lib/views/Admin/admin_dashboard.drt b/lib/views/Admin/admin_dashboard.dart similarity index 100% rename from lib/views/Admin/admin_dashboard.drt rename to lib/views/Admin/admin_dashboard.dart From b670f426979166eb1aae85da1122831745f311a8 Mon Sep 17 00:00:00 2001 From: Septian Jauhariansyah Date: Wed, 24 Sep 2025 22:57:58 +0700 Subject: [PATCH 4/4] update the readme file --- README.md | 115 +++++++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index d2dc923..64ccc2a 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,56 @@

Hello, Waving hand animated gif I'm Md Shirajul Islam

+ width="45" /> My Name is Septian ## About The Project -LC LMS is a cutting-edge online learning management system built with Flutter, offering a seamless and engaging educational experience. This mobile app empowers users with a user-friendly interface, interactive content delivery, and robust features for efficient learning. Whether you're a student or an instructor, LC LMS provides a dynamic platform for accessing courses, submitting assignments, and fostering collaboration. Experience the future of online education with LC LMS – where innovation meets education, all in the palm of your hand. +This is a fork of [interactive_cares_lms](https://github.com/programmingwormhole/interactive_cares_lms), a Flutter-based Learning Management System (LMS). +I extended it by adding role-based authentication and dashboards for different user types: - -## Demo Access -[![Download][Download]][Download-url] - - -### Built With - -LC LMS, crafted with the power of Dart and Flutter, redefines online learning. This dynamic app seamlessly blends innovation and education, providing a sleek, responsive, and user-friendly experience. Whether you're a student or instructor, dive into a world of interactive courses, streamlined assignments, and collaborative tools. LC LMS is the epitome of modern education, built for the future with Dart and Flutter's cutting-edge technology. +* **Admin** 👨‍💻 – Manage courses, users, and system settings. +* **Lecturer** 👩‍🏫 – Create and manage lessons. +* **Student** 🎓 – Enroll in courses and track progress. -[![Flutter][Flutter]][Flutter-url] -[![Dart][Dart]][Dart-url] +--- + +## 🚀 Features +### 🔑 Authentication +* Login & Register with API integration +* Role-based redirection (Admin, Lecturer, Student) + +### 📚 Course Management +* Featured courses, lessons, and modules +* Track lesson completion progress + +### 📌 Bookmarking +* Save & manage bookmarked lessons locally + +### 🎨 UI +* Flutter + GetX state management +* Material Design widgets + +--- +## Project Structure +```bash +lib/ +├── bindings/ # GetX dependency bindings +├── controllers/ # App controllers (auth, course, lesson, bookmark) +├── core/services/ # API services (auth, shared services) +├── global_widgets/ # Reusable UI components +├── helpers/ # Helpers (requests, forms, alerts) +├── models/ # Data models (user, course, category) +├── routes/ # Route names & destinations +├── utils/ # Config, constants, colors, assets +├── views/ # Screens (Authentication, Home, Learning, etc.) +│ ├── Admin/ # NEW: Admin dashboard +│ ├── Lecturer/ # NEW: Lecturer dashboard +│ └── Student/ # NEW: Student dashboard +└── main.dart # App entry point with role-based redirection +``` +--- ## Getting Started @@ -37,55 +68,33 @@ Follow the below steps to run the application on your device. 1. Clone the repo ```sh - git clone https://github.com/programmingwormhole/interactive_cares_lms.git - ``` -2. Open Project In IDE - ```sh - Android Studio, VS Code, or any other Flutter Supported IDE + git clone https://github.com//interactive_cares_lms.git + cd interactive_cares_lms + ``` -3. Get Dependencies +2. Get Dependencies ```js flutter pub get ``` -4. Run +3. Run ```js flutter run ``` -## Key Features -- [x] Authentication using RestAPI. -- [x] Keep logged-in user by storing bearer token. -- [x] Home Screen UI -- [x] Bookmark screen with functionality -- [x] Play a lesson from the bookmark to a specific time in the video. -- [x] Enrolled Course Screen UI with functionality. -- [x] Real-time course complete progress. -- [x] Course modules -- [x] Course lesson -- [x] Previous or Next lesson system from the lesson screen -- [x] Mark as complete a lesson -- [x] After completing all lessons in a course students will get an animated dialogue to claim a certificate. +## Role Based Authentication +- On login, users are redirected to different dashboards based on their role. +- For now, roles are stored in a local mock JSON (assets/json/fake_auth.json) for testing. +- Future updates will connect to a backend API with real role-based authentication. -## Packages -- [x] GetX (For State management) -- [x] http (For API request) -- [x] flutter_svg (To display SVG icon in the app) -- [x] lottie (To display animation in the app) -- [x] shared_preferences (To store data in local storage) -- [x] google_fonts (To use custom fonts) -- [x] carousel_slider (For creating an image slider) -- [x] page_view_dot_indicator (To show a slider dot indicator) -- [x] flutter_staggered_grid_view (To make a user-friendly grid view) -- [x] video_player & chewie (To play video from network or assets) - - - - -[Flutter]: https://camo.githubusercontent.com/b6d2d66adc138025ea9cdf8444cdc29a588c98d062c263f8651ba6b7ad46fef0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f466c75747465722d2532333032353639422e7376673f7374796c653d666f722d7468652d6261646765266c6f676f3d466c7574746572266c6f676f436f6c6f723d7768697465 -[Flutter-url]: https://flutter.dev -[Dart]: https://camo.githubusercontent.com/a0a1ad90011aa02e7e6f32be4998b8843f0884eed20b575c8a2189859550824d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646172742d2532333031373543322e7376673f7374796c653d666f722d7468652d6261646765266c6f676f3d64617274266c6f676f436f6c6f723d7768697465 -[Dart-url]: https://dart.dev -[Download]: https://camo.envatousercontent.com/66cff805c4d35c74668291a51e21f978424565d9/68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f70726f6772616d6d696e67776f726d686f6c652f656e7661746f2f6d61696e2f64656d6f2e676966 -[Download-url]: https://raw.githubusercontent.com/programmingwormhole/interactive_cares_lms/main/lc_lms_demo.apk +## Roadmap +- [x]Connect role management to backend API +- [x]Add course creation for lecturers +- [x]Add course/user management for admins +- [x]Enhance student dashboard with certificates & progress tracking + +--- +## Credit +* Original Project [Interactive Cares LMS](https://github.com/programmingwormhole/interactive_cares_lms) +* Extended by [Septian Jauhariansyah](https://github.com/alchemista27) \ No newline at end of file