displayed project list table on dashboart screen page
This commit is contained in:
parent
b9e2f72d11
commit
350fe3d9ce
28
lib/api/api_client.dart
Normal file
28
lib/api/api_client.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
class ApiClient {
|
||||||
|
static final ApiClient instance = ApiClient('http://10.0.2.2:5032/api');
|
||||||
|
final String _baseUrl;
|
||||||
|
|
||||||
|
ApiClient(this._baseUrl);
|
||||||
|
|
||||||
|
Future<http.Response> get(String endpoint) async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
final token = prefs.getString('auth_token');
|
||||||
|
|
||||||
|
if (token == null) {
|
||||||
|
throw Exception('No token found. User might not be logged in.');
|
||||||
|
}
|
||||||
|
|
||||||
|
final url = '$_baseUrl/$endpoint';
|
||||||
|
print("Url received: $url");
|
||||||
|
final headers = {
|
||||||
|
'Authorization': 'Bearer $token',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
};
|
||||||
|
|
||||||
|
return await http.get(Uri.parse(url), headers: headers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
22
lib/api/api_service.dart
Normal file
22
lib/api/api_service.dart
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'package:maxdash/api/api_client.dart';
|
||||||
|
|
||||||
|
class ApiService {
|
||||||
|
final ApiClient _apiClient = ApiClient.instance;
|
||||||
|
|
||||||
|
Future<dynamic> getProjectSummaries() async {
|
||||||
|
try {
|
||||||
|
final response = await _apiClient.get('project/list');
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
// print('Response body: ${response.body}'); // Parsed JSON
|
||||||
|
return jsonDecode(response.body);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw Exception('Failed to load project summaries: ${response.statusCode}');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception('Error in getProjectSummaries: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,12 +2,15 @@ import 'package:maxdash/controller/my_controller.dart';
|
|||||||
import 'package:maxdash/model/chart_model.dart';
|
import 'package:maxdash/model/chart_model.dart';
|
||||||
import 'package:maxdash/model/project_summary_model.dart';
|
import 'package:maxdash/model/project_summary_model.dart';
|
||||||
import 'package:maxdash/model/task_list_model.dart';
|
import 'package:maxdash/model/task_list_model.dart';
|
||||||
|
import 'package:maxdash/model/ProjectSummaryApiModel.dart';
|
||||||
|
import 'package:maxdash/api/api_service.dart';
|
||||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||||
|
|
||||||
class ProjectController extends MyController {
|
class ProjectController extends MyController {
|
||||||
TooltipBehavior? tooltipBehavior;
|
TooltipBehavior? tooltipBehavior;
|
||||||
List<TaskListModel> task = [];
|
List<TaskListModel> task = [];
|
||||||
List<ProjectSummaryModel> projectSummary = [];
|
List<ProjectSummaryModel> projectSummary = []; // Dummy data (local)
|
||||||
|
List<ProjectSummaryApiModel> projectSummaryApiList = []; // API data
|
||||||
List<ChartSampleData>? chartData;
|
List<ChartSampleData>? chartData;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -20,6 +23,11 @@ class ProjectController extends MyController {
|
|||||||
projectSummary = value.sublist(0, 5);
|
projectSummary = value.sublist(0, 5);
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fetch project summary from API
|
||||||
|
fetchProjectSummariesFromApi();
|
||||||
|
|
||||||
|
// Dummy chart data
|
||||||
chartData = <ChartSampleData>[
|
chartData = <ChartSampleData>[
|
||||||
ChartSampleData(x: 'Jan', y: 10, secondSeriesYValue: 8, thirdSeriesYValue: 12),
|
ChartSampleData(x: 'Jan', y: 10, secondSeriesYValue: 8, thirdSeriesYValue: 12),
|
||||||
ChartSampleData(x: 'Feb', y: 5, secondSeriesYValue: 6, thirdSeriesYValue: 7),
|
ChartSampleData(x: 'Feb', y: 5, secondSeriesYValue: 6, thirdSeriesYValue: 7),
|
||||||
@ -43,4 +51,19 @@ class ProjectController extends MyController {
|
|||||||
task.isSelectTask = !task.isSelectTask;
|
task.isSelectTask = !task.isSelectTask;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> fetchProjectSummariesFromApi() async {
|
||||||
|
try {
|
||||||
|
final response = await ApiService().getProjectSummaries();
|
||||||
|
|
||||||
|
if (response != null && response is List) {
|
||||||
|
projectSummaryApiList = response
|
||||||
|
.map<ProjectSummaryApiModel>((json) => ProjectSummaryApiModel.fromJson(json))
|
||||||
|
.toList();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print('Error loading API project summaries: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
31
lib/model/ProjectSummaryApiModel.dart
Normal file
31
lib/model/ProjectSummaryApiModel.dart
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
class ProjectSummaryApiModel {
|
||||||
|
final int id;
|
||||||
|
final String name;
|
||||||
|
final String projectAddress;
|
||||||
|
final String contactPerson;
|
||||||
|
final DateTime startDate;
|
||||||
|
final DateTime endDate;
|
||||||
|
final int projectStatusId;
|
||||||
|
|
||||||
|
ProjectSummaryApiModel({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.projectAddress,
|
||||||
|
required this.contactPerson,
|
||||||
|
required this.startDate,
|
||||||
|
required this.endDate,
|
||||||
|
required this.projectStatusId,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ProjectSummaryApiModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return ProjectSummaryApiModel(
|
||||||
|
id: json['id'],
|
||||||
|
name: json['name'],
|
||||||
|
projectAddress: json['projectAddress'],
|
||||||
|
contactPerson: json['contactPerson'],
|
||||||
|
startDate: DateTime.parse(json['startDate']),
|
||||||
|
endDate: DateTime.parse(json['endDate']),
|
||||||
|
projectStatusId: json['projectStatusId'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -370,66 +370,55 @@ class _ProjectScreenState extends State<ProjectScreen> with UIMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget projectSummary() {
|
Widget projectSummary() {
|
||||||
return MyCard.bordered(
|
return MyCard.bordered(
|
||||||
borderRadiusAll: 4,
|
borderRadiusAll: 4,
|
||||||
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
|
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
|
||||||
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
|
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
|
||||||
paddingAll: 24,
|
paddingAll: 24,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
MyText.bodyMedium("Project Summary", fontWeight: 600),
|
MyText.bodyMedium("Project Summary", fontWeight: 600),
|
||||||
MySpacing.height(24),
|
MySpacing.height(24),
|
||||||
SingleChildScrollView(
|
SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: DataTable(
|
child: DataTable(
|
||||||
sortAscending: true,
|
sortAscending: true,
|
||||||
columnSpacing: 84,
|
columnSpacing: 84,
|
||||||
onSelectAll: (_) => {},
|
onSelectAll: (_) => {},
|
||||||
headingRowColor: WidgetStatePropertyAll(contentTheme.primary.withAlpha(40)),
|
headingRowColor: WidgetStatePropertyAll(contentTheme.primary.withAlpha(40)),
|
||||||
dataRowMaxHeight: 60,
|
dataRowMaxHeight: 60,
|
||||||
showBottomBorder: true,
|
showBottomBorder: true,
|
||||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||||
border: TableBorder.all(borderRadius: BorderRadius.circular(4), style: BorderStyle.solid, width: .4, color: Colors.grey),
|
border: TableBorder.all(
|
||||||
columns: [
|
borderRadius: BorderRadius.circular(4),
|
||||||
DataColumn(label: MyText.labelLarge('S.No', color: contentTheme.primary)),
|
style: BorderStyle.solid,
|
||||||
DataColumn(label: MyText.labelLarge('Title', color: contentTheme.primary)),
|
width: .4,
|
||||||
DataColumn(label: MyText.labelLarge('Assign to', color: contentTheme.primary)),
|
color: Colors.grey,
|
||||||
DataColumn(label: MyText.labelLarge('Due Date', color: contentTheme.primary)),
|
),
|
||||||
DataColumn(label: MyText.labelLarge('Priority', color: contentTheme.primary)),
|
columns: [
|
||||||
DataColumn(label: MyText.labelLarge('Status', color: contentTheme.primary)),
|
DataColumn(label: MyText.labelLarge('S.No', color: contentTheme.primary)),
|
||||||
DataColumn(label: MyText.labelLarge('Action', color: contentTheme.primary)),
|
DataColumn(label: MyText.labelLarge('Name', color: contentTheme.primary)),
|
||||||
],
|
DataColumn(label: MyText.labelLarge('Address', color: contentTheme.primary)),
|
||||||
rows: controller.projectSummary
|
DataColumn(label: MyText.labelLarge('Contact Person', color: contentTheme.primary)),
|
||||||
.mapIndexed((index, data) => DataRow(cells: [
|
DataColumn(label: MyText.labelLarge('Start Date', color: contentTheme.primary)),
|
||||||
DataCell(MyText.bodyMedium("#${data.id}", fontWeight: 600)),
|
DataColumn(label: MyText.labelLarge('End Date', color: contentTheme.primary)),
|
||||||
DataCell(MyText.bodyMedium(data.title, fontWeight: 600)),
|
DataColumn(label: MyText.labelLarge('Status ID', color: contentTheme.primary)),
|
||||||
DataCell(MyText.bodyMedium(data.assignTo, fontWeight: 600)),
|
],
|
||||||
DataCell(MyText.bodyMedium(Utils.getDateStringFromDateTime(data.date), fontWeight: 600)),
|
rows: controller.projectSummaryApiList
|
||||||
DataCell(MyText.bodyMedium(data.priority, fontWeight: 600)),
|
.mapIndexed((index, data) => DataRow(cells: [
|
||||||
DataCell(MyText.bodyMedium(data.status, fontWeight: 600)),
|
DataCell(MyText.bodyMedium("#${index + 1}", fontWeight: 600)),
|
||||||
DataCell(Row(
|
DataCell(MyText.bodyMedium(data.name, fontWeight: 600)),
|
||||||
children: [
|
DataCell(MyText.bodyMedium(data.projectAddress, fontWeight: 600)),
|
||||||
MyContainer(
|
DataCell(MyText.bodyMedium(data.contactPerson, fontWeight: 600)),
|
||||||
onTap: () {},
|
DataCell(MyText.bodyMedium(Utils.getDateStringFromDateTime(data.startDate), fontWeight: 600)),
|
||||||
color: contentTheme.primary,
|
DataCell(MyText.bodyMedium(Utils.getDateStringFromDateTime(data.endDate), fontWeight: 600)),
|
||||||
paddingAll: 8,
|
DataCell(MyText.bodyMedium(data.projectStatusId.toString(), fontWeight: 600)),
|
||||||
child: Icon(LucideIcons.download, size: 16, color: contentTheme.onPrimary),
|
]))
|
||||||
),
|
|
||||||
MySpacing.width(12),
|
|
||||||
MyContainer(
|
|
||||||
onTap: () {},
|
|
||||||
color: contentTheme.secondary,
|
|
||||||
paddingAll: 8,
|
|
||||||
child: Icon(LucideIcons.pencil, size: 16, color: contentTheme.onPrimary),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
))
|
|
||||||
]))
|
|
||||||
.toList()),
|
.toList()),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.2"
|
version: "1.1.2"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||||
|
@ -59,6 +59,7 @@ dependencies:
|
|||||||
syncfusion_flutter_calendar: ^28.2.6
|
syncfusion_flutter_calendar: ^28.2.6
|
||||||
syncfusion_flutter_maps: ^28.1.33
|
syncfusion_flutter_maps: ^28.1.33
|
||||||
http: ^1.2.2
|
http: ^1.2.2
|
||||||
|
collection: ^1.18.0
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
Loading…
x
Reference in New Issue
Block a user