Skip to content

Commit 89bd364

Browse files
committed
ultimo dia de aula
1 parent ef06561 commit 89bd364

19 files changed

+525
-114
lines changed

lib/app/module/home/controller/home_controller.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,6 @@ class HomeController extends Cubit<HomeState> {
3131
final projects = await _projectService.findByStatus(status);
3232
emit(state.copyWith(projects: projects, status: HomeStatus.complete, projectFilter: status));
3333
}
34+
35+
Future<void> updateList() => filter(state.projectFilter);
3436
}

lib/app/module/home/widgets/project_tile.dart

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
22
import 'package:flutter_modular/flutter_modular.dart';
33

44
import 'package:job_time/app/core/ui/job_timer_icons_icons.dart';
5+
import 'package:job_time/app/module/home/controller/home_controller.dart';
56
import 'package:job_time/app/view_models/project_model.dart';
67

78
class ProjectTile extends StatelessWidget {
@@ -13,24 +14,30 @@ class ProjectTile extends StatelessWidget {
1314

1415
@override
1516
Widget build(BuildContext context) {
16-
return Container(
17-
//? Não faz sentido, uma vez que foi usado um Expanded como filho, e ocupará todo o espaço disponível
18-
// constraints: const BoxConstraints(maxHeight: 90),
19-
height: 90,
20-
margin: const EdgeInsets.all(10),
21-
decoration: BoxDecoration(
22-
borderRadius: BorderRadius.circular(10),
23-
border: Border.all(
24-
color: Colors.grey[300]!,
25-
width: 4,
17+
return InkWell(
18+
onTap: () async {
19+
await Modular.to.pushNamed('/project/detail', arguments: projectModel);
20+
Modular.get<HomeController>().updateList();
21+
},
22+
child: Container(
23+
//? Não faz sentido, uma vez que foi usado um Expanded como filho, e ocupará todo o espaço disponível
24+
// constraints: const BoxConstraints(maxHeight: 90),
25+
height: 90,
26+
margin: const EdgeInsets.all(10),
27+
decoration: BoxDecoration(
28+
borderRadius: BorderRadius.circular(10),
29+
border: Border.all(
30+
color: Colors.grey[300]!,
31+
width: 4,
32+
),
33+
),
34+
child: Column(
35+
// mainAxisSize: MainAxisSize.min,
36+
children: [
37+
_ProjectName(projectModel: projectModel),
38+
Expanded(child: _ProjectProgress(projectModel: projectModel)),
39+
],
2640
),
27-
),
28-
child: Column(
29-
// mainAxisSize: MainAxisSize.min,
30-
children: [
31-
_ProjectName(projectModel: projectModel),
32-
Expanded(child: _ProjectProgress(projectModel: projectModel)),
33-
],
3441
),
3542
);
3643
}
@@ -44,21 +51,18 @@ class _ProjectName extends StatelessWidget {
4451

4552
@override
4653
Widget build(BuildContext context) {
47-
return InkWell(
48-
onTap: () => Modular.to.pushNamed('/project/detail', arguments: projectModel),
49-
child: Padding(
50-
padding: const EdgeInsets.all(8.0),
51-
child: Row(
52-
mainAxisAlignment: MainAxisAlignment.spaceBetween,
53-
children: [
54-
Text(projectModel.name),
55-
Icon(
56-
JobTimerIcons.angle_double_right,
57-
size: 20,
58-
color: Theme.of(context).primaryColor,
59-
),
60-
],
61-
),
54+
return Padding(
55+
padding: const EdgeInsets.all(8.0),
56+
child: Row(
57+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
58+
children: [
59+
Text(projectModel.name),
60+
Icon(
61+
JobTimerIcons.angle_double_right,
62+
size: 20,
63+
color: Theme.of(context).primaryColor,
64+
),
65+
],
6266
),
6367
);
6468
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:flutter_bloc/flutter_bloc.dart';
3+
import 'package:job_time/app/services/projects/project_service.dart';
4+
import 'package:job_time/app/view_models/project_model.dart';
5+
6+
part 'project_detail_state.dart';
7+
8+
class ProjectDetailController extends Cubit<ProjectDetailState> {
9+
final ProjectService _projectService;
10+
11+
ProjectDetailController({required ProjectService projectService})
12+
: _projectService = projectService,
13+
super(const ProjectDetailState.initial());
14+
15+
void setProjectProject(ProjectModel projectModel) {
16+
emit(state.copyWith(projectModel: projectModel, status: ProjectDetailStatus.complete));
17+
}
18+
19+
Future<void> updateProject() async {
20+
final project = await _projectService.findById(state.projectModel!.id!);
21+
emit(state.copyWith(projectModel: project));
22+
}
23+
24+
Future<void> finishProject() async {
25+
try {
26+
emit(state.copyWith(status: ProjectDetailStatus.loading));
27+
final projectId = state.projectModel!.id!;
28+
await _projectService.finish(projectId);
29+
await updateProject();
30+
emit(state.copyWith(status: ProjectDetailStatus.complete));
31+
} catch (_) {
32+
emit(state.copyWith(status: ProjectDetailStatus.failure));
33+
}
34+
}
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
part of 'project_detail_controller.dart';
2+
3+
enum ProjectDetailStatus {
4+
initial,
5+
loading,
6+
complete,
7+
failure,
8+
}
9+
10+
class ProjectDetailState extends Equatable {
11+
final ProjectDetailStatus status;
12+
final ProjectModel? projectModel;
13+
14+
const ProjectDetailState._({
15+
required this.status,
16+
this.projectModel,
17+
});
18+
19+
const ProjectDetailState.initial()
20+
: status = ProjectDetailStatus.initial,
21+
projectModel = null;
22+
23+
ProjectDetailState copyWith({
24+
ProjectDetailStatus? status,
25+
ProjectModel? projectModel,
26+
}) {
27+
return ProjectDetailState._(
28+
status: status ?? this.status,
29+
projectModel: projectModel ?? this.projectModel,
30+
);
31+
}
32+
33+
@override
34+
List<Object?> get props => [status, projectModel];
35+
}
Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
11
import 'package:flutter_modular/flutter_modular.dart';
2+
import 'package:job_time/app/module/project/detail/controller/project_detail_controller.dart';
23
import 'package:job_time/app/module/project/detail/project_detail_page.dart';
4+
import 'package:job_time/app/view_models/project_model.dart';
5+
import 'package:modular_bloc_bind/modular_bloc_bind.dart';
36

47
class ProjectDetailModule extends Module {
8+
@override
9+
List<Bind<Object>> get binds => [
10+
BlocBind.lazySingleton(
11+
(i) => ProjectDetailController(projectService: i()), // AppModule
12+
),
13+
];
14+
515
@override
616
List<ModularRoute> get routes => [
7-
ChildRoute('/', child: (context, args) => const ProjectDetailPage()),
17+
ChildRoute('/', child: (context, args) {
18+
final ProjectModel projectModel = args.data;
19+
return ProjectDetailPage(
20+
controller: Modular.get()..setProjectProject(projectModel),
21+
);
22+
}),
823
];
924
}
Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,93 @@
1+
import 'package:asuka/asuka.dart';
12
import 'package:flutter/material.dart';
3+
import 'package:flutter_bloc/flutter_bloc.dart';
24
import 'package:job_time/app/core/ui/job_timer_icons_icons.dart';
5+
import 'package:job_time/app/entities/project_status.dart';
6+
import 'package:job_time/app/module/project/detail/controller/project_detail_controller.dart';
37
import 'package:job_time/app/module/project/detail/widgets/project_detail_appbar.dart';
48
import 'package:job_time/app/module/project/detail/widgets/project_detail_pie_chart.dart';
5-
import 'package:job_time/app/module/project/detail/widgets/project_detail_task_tile.dart';
9+
import 'package:job_time/app/module/project/detail/widgets/project_detail_tile.dart';
10+
import 'package:job_time/app/view_models/project_model.dart';
611

712
class ProjectDetailPage extends StatelessWidget {
8-
const ProjectDetailPage({Key? key}) : super(key: key);
13+
final ProjectDetailController controller;
14+
const ProjectDetailPage({Key? key, required this.controller}) : super(key: key);
915

1016
@override
1117
Widget build(BuildContext context) {
1218
return Scaffold(
13-
body: CustomScrollView(
14-
slivers: [
15-
ProjectDetailApp(),
16-
SliverList(
17-
delegate: SliverChildListDelegate([
18-
const Padding(
19-
padding: EdgeInsets.only(top: 50, bottom: 50),
20-
child: ProjectDetailPieChart(),
19+
body: BlocConsumer<ProjectDetailController, ProjectDetailState>(
20+
bloc: controller,
21+
listener: (context, state) {
22+
if (state.status == ProjectDetailStatus.failure) {
23+
AsukaSnackbar.alert('Erro interno').show();
24+
}
25+
},
26+
builder: (context, state) {
27+
final projectModel = state.projectModel;
28+
switch (state.status) {
29+
case ProjectDetailStatus.initial:
30+
return const Center(
31+
child: Text('Carregando Projeto'),
32+
);
33+
case ProjectDetailStatus.loading:
34+
return const Center(
35+
child: CircularProgressIndicator.adaptive(),
36+
);
37+
case ProjectDetailStatus.complete:
38+
return _buildProjectDetail(context, projectModel!);
39+
case ProjectDetailStatus.failure:
40+
if (projectModel != null) {
41+
return _buildProjectDetail(context, projectModel);
42+
}
43+
return const Center(
44+
child: Text('Erro ao carregar o projeto'),
45+
);
46+
}
47+
},
48+
),
49+
);
50+
}
51+
52+
Widget _buildProjectDetail(BuildContext context, ProjectModel projectModel) {
53+
final totalTask = projectModel.tasks.fold<int>(0, (totalValue, task) => totalValue += task.duration);
54+
return CustomScrollView(
55+
slivers: [
56+
ProjectDetailApp(
57+
projectModel: projectModel,
58+
),
59+
SliverList(
60+
delegate: SliverChildListDelegate([
61+
Padding(
62+
padding: const EdgeInsets.only(top: 50, bottom: 50),
63+
child: ProjectDetailPieChart(
64+
projectEstimate: projectModel.estimate,
65+
totalTask: totalTask,
2166
),
22-
const ProjectDetailTaskTile(),
23-
const ProjectDetailTaskTile(),
24-
const ProjectDetailTaskTile(),
25-
const ProjectDetailTaskTile(),
26-
const ProjectDetailTaskTile(),
27-
const ProjectDetailTaskTile(),
28-
const ProjectDetailTaskTile(),
29-
]),
30-
),
31-
SliverFillRemaining(
32-
hasScrollBody: false,
33-
child: Align(
34-
alignment: Alignment.bottomRight,
67+
),
68+
...projectModel.tasks.map((task) => ProjectDetailTile(task)).toList(),
69+
]),
70+
),
71+
SliverFillRemaining(
72+
hasScrollBody: false,
73+
child: Align(
74+
alignment: Alignment.bottomRight,
75+
child: Visibility(
76+
visible: projectModel.status != ProjectStatus.finalizado,
3577
child: Padding(
3678
padding: const EdgeInsets.all(15),
3779
child: ElevatedButton.icon(
38-
onPressed: () {},
80+
onPressed: () {
81+
controller.finishProject();
82+
},
3983
icon: const Icon(JobTimerIcons.ok_circled2),
4084
label: const Text('Finalizar Projeto'),
4185
),
4286
),
4387
),
44-
)
45-
],
46-
),
88+
),
89+
)
90+
],
4791
);
4892
}
4993
}

lib/app/module/project/detail/widgets/project_detail_appbar.dart

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter_modular/flutter_modular.dart';
3+
import 'package:job_time/app/entities/project_status.dart';
4+
import 'package:job_time/app/module/project/detail/controller/project_detail_controller.dart';
5+
import 'package:job_time/app/view_models/project_model.dart';
26

37
class ProjectDetailApp extends SliverAppBar {
4-
ProjectDetailApp({Key? key})
8+
ProjectDetailApp({super.key, required ProjectModel projectModel})
59
: super(
6-
key: key,
710
expandedHeight: 100,
811
pinned: true,
912
toolbarHeight: 100,
10-
title: const Text('Project Detail'),
13+
title: Text(projectModel.name),
1114
centerTitle: true,
1215
shape: const RoundedRectangleBorder(
1316
borderRadius: BorderRadius.vertical(
@@ -29,9 +32,13 @@ class ProjectDetailApp extends SliverAppBar {
2932
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.white),
3033
child: Row(
3134
mainAxisAlignment: MainAxisAlignment.spaceBetween,
32-
children: const [
33-
Text('10 task'),
34-
_NewTasks(),
35+
children: [
36+
Text('${projectModel.tasks.length} task'),
37+
Visibility(
38+
visible: projectModel.status != ProjectStatus.finalizado,
39+
replacement: const Text('Projeto Finalizado'),
40+
child: _NewTasks(projectModel: projectModel),
41+
),
3542
],
3643
),
3744
),
@@ -44,21 +51,29 @@ class ProjectDetailApp extends SliverAppBar {
4451
}
4552

4653
class _NewTasks extends StatelessWidget {
47-
const _NewTasks({Key? key}) : super(key: key);
54+
final ProjectModel projectModel;
55+
// ignore: unused_element
56+
const _NewTasks({super.key, required this.projectModel});
4857

4958
@override
5059
Widget build(BuildContext context) {
51-
return Row(
52-
children: [
53-
Padding(
54-
padding: const EdgeInsets.symmetric(vertical: 8),
55-
child: CircleAvatar(
56-
backgroundColor: Theme.of(context).primaryColor,
57-
child: const Icon(Icons.add, color: Colors.white, size: 20),
60+
return InkWell(
61+
onTap: () async {
62+
await Modular.to.pushNamed('/project/task/', arguments: projectModel);
63+
Modular.get<ProjectDetailController>().updateProject();
64+
},
65+
child: Row(
66+
children: [
67+
Padding(
68+
padding: const EdgeInsets.symmetric(vertical: 8),
69+
child: CircleAvatar(
70+
backgroundColor: Theme.of(context).primaryColor,
71+
child: const Icon(Icons.add, color: Colors.white, size: 20),
72+
),
5873
),
59-
),
60-
const Text('Adicionar Task'),
61-
],
74+
const Text('Adicionar Task'),
75+
],
76+
),
6277
);
6378
}
6479
}

0 commit comments

Comments
 (0)