Skip to content

Commit

Permalink
Merge pull request #114 from fga-eps-mds/feat#71/US10-Gerenciar-area-…
Browse files Browse the repository at this point in the history
…de-conhecimento

[FEAT] Tela area de conhecimentos (fga-eps-mds/2024.2-ARANDU-DOC#71)
  • Loading branch information
GabrielCostaDeOliveira authored Feb 9, 2025
2 parents c7c6949 + 088ac71 commit 64414b9
Show file tree
Hide file tree
Showing 29 changed files with 994 additions and 168 deletions.
2 changes: 2 additions & 0 deletions lib/core/di/locator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:aranduapp/core/network/token_manager/di/di_auth.dart';
import 'package:aranduapp/ui/edit_delete_user/di/di_edit_delete_user.dart';
import 'package:aranduapp/ui/edit_password/di/di_edit_password.dart';
import 'package:aranduapp/ui/edit_profile/di/di_edit_profile.dart';
import 'package:aranduapp/ui/knowledge/di/di.dart';
import 'package:aranduapp/ui/journey/di/di.dart';
import 'package:aranduapp/ui/login/di/di_login.dart';
import 'package:aranduapp/ui/navbar/di/di_navbar.dart';
Expand Down Expand Up @@ -35,4 +36,5 @@ void setupLocator() {
setupJoinSubjectsDI();
setupTrailsDI();
setupPagesContentDI();
setupknowledgeDI();
}
1 change: 0 additions & 1 deletion lib/ui/edit_profile/di/di_edit_profile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@ final GetIt locator = GetIt.instance;

void setupEditProfileDI() {
locator.registerLazySingleton(() => EditProfileService());

locator.registerFactory(() => EditProfileViewModel());
}
12 changes: 0 additions & 12 deletions lib/ui/home/view/home_view.dart

This file was deleted.

10 changes: 10 additions & 0 deletions lib/ui/knowledge/di/di.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:aranduapp/ui/knowledge/service/knowledge_service.dart';
import 'package:aranduapp/ui/knowledge/viewmodel/knowledge_viewmodel.dart';
import 'package:get_it/get_it.dart';

final GetIt locator = GetIt.instance;

void setupknowledgeDI() {
locator.registerLazySingleton(() => KnowledgeService());
locator.registerFactory(() => KnowledgeViewmodel());
}
23 changes: 23 additions & 0 deletions lib/ui/knowledge/model/knowledge_request.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'dart:convert';

class KnowledgeRequest {
final String name;
final String id;
final String description;

KnowledgeRequest(
{required this.name, required this.id, required this.description});

Map<String, dynamic> toJson() {
return <String, dynamic>{'name': name, '_id': id};
}

factory KnowledgeRequest.fromJsonString(String jsonString) {
final json = jsonDecode(jsonString);

return KnowledgeRequest(
name: json['name']! as String,
id: json['_id']! as String,
description: json["description"]! as String);
}
}
40 changes: 40 additions & 0 deletions lib/ui/knowledge/service/knowledge_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:aranduapp/core/log/log.dart';
import 'package:aranduapp/core/network/studio_maker_api.dart';
import 'package:dio/dio.dart';

class KnowledgeService {
Future<List<Map<String, dynamic>>?> getKnowledges() async {
try {
String path = '/knowledges';
Response response = await StudioMakerApi.getInstance().get(path: path);
if (response.statusCode == 200 && response.data != null) {
return List<Map<String, dynamic>>.from(response.data);
} else {
Log.e('Erro ao buscar áreas de conhecimento:${response.statusCode}');
return null;
}
} catch (e) {
Log.e('Erro na requisição $e');
return null;
}
}

Future<List<Map<String, dynamic>>?> getSubjectsByKnowledges(
String knowledgeId, String name) async {
try {
String path = '/knowledges/$knowledgeId/subjects';
Response response = await StudioMakerApi.getInstance().get(path: path);
if (response.statusCode == 200 && response.data != null) {
final data = response.data;
final subjectsList = data['subjects'];
return List<Map<String, dynamic>>.from(subjectsList);
} else {
Log.e('Erro ao buscar as disciplinas de $name :${response.statusCode}');
return null;
}
} catch (e) {
Log.e('Erro na requisição $e');
return null;
}
}
}
249 changes: 249 additions & 0 deletions lib/ui/knowledge/view/knowledge_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
import 'package:aranduapp/ui/subjects/view/subjects_view.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:get_it/get_it.dart';
import 'package:aranduapp/ui/knowledge/viewmodel/knowledge_viewmodel.dart';
import 'package:aranduapp/ui/shared/grafismo.dart';

class KnowledgeView extends StatefulWidget {
const KnowledgeView({super.key});

@override
State<KnowledgeView> createState() => _KnowledgeViewState();
}

class _KnowledgeViewState extends State<KnowledgeView> {
final KnowledgeViewmodel viewModel = GetIt.instance<KnowledgeViewmodel>();

@override
void initState() {
super.initState();
viewModel.fetchKnowledgesCommand.execute(null);
}

@override
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;

return Scaffold(
appBar: AppBar(
toolbarHeight: 0,
backgroundColor: Theme.of(context).colorScheme.primary,
elevation: 0,
),
body: Stack(
children: [
Positioned(
child: CustomPaint(
size: const Size(double.infinity, kToolbarHeight),
painter: CustomPatternPainter(colors),
),
),
ListView(
padding: EdgeInsets.zero,
children: [
const SizedBox(height: kToolbarHeight),
_logo(context),
const SizedBox(height: 20),
_searchbar(context),
const SizedBox(height: 40),
_knowledgeCarousel(context),
],
),
],
),
);
}

Widget _logo(BuildContext context) {
Size screenSize = MediaQuery.of(context).size;
double circleDiameter = screenSize.longestSide * 0.7;
return Center(
child: Column(
children: [
Stack(
alignment: Alignment.center,
children: [
// Círculo de fundo
Container(
width: circleDiameter * 0.3,
height: circleDiameter * 0.3,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
shape: BoxShape.circle,
),
),
// Imagem com deslocamento para a esquerda
Transform.translate(
offset: const Offset(-10, 0),
child: Image.asset(
'assets/images/Logo.png',
width: circleDiameter * 0.24,
height: circleDiameter * 0.24,
fit: BoxFit.contain,
),
),
],
),
Text(
"Arandú",
style: GoogleFonts.amarante(
textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith(
fontSize: MediaQuery.of(context).size.height * 0.05,
fontWeight: FontWeight.w500,
),
),
),
],
),
);
}

Widget _searchbar(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0, vertical: 16.0),
child: SearchAnchor(
builder: (BuildContext context, SearchController controller) {
return SearchBar(
backgroundColor: WidgetStatePropertyAll<Color>(
Theme.of(context).colorScheme.surface,
),
hintText: 'Pesquisar',
leading: const Icon(Icons.search),
padding: const WidgetStatePropertyAll<EdgeInsets>(
EdgeInsets.symmetric(horizontal: 16.0),
),
shape: WidgetStatePropertyAll<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: const BorderRadius.all(Radius.circular(12.0)),
side: BorderSide(
color: Theme.of(context).colorScheme.onSurface,
),
),
),
elevation: const WidgetStatePropertyAll<double>(0.0),
onTap: () {
controller.openView();
},
onChanged: (_) {
controller.openView();
},
);
},
suggestionsBuilder:
(BuildContext context, SearchController controller) {
return List<ListTile>.generate(5, (int index) {
final String materia = 'Materia $index';
return ListTile(
title: Text(materia),
onTap: () {
controller.closeView(materia);
},
);
});
},
),
);
}

Widget _knowledgecard({
required BuildContext context,
required Map<String, dynamic> item,
}) {
return InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Subject(knowledgeId: item['_id'],)),
);
},
borderRadius: BorderRadius.circular(4.0),
child: Card(
elevation: 4.0,
child: SizedBox(
width: 360,
height: 116,
child: Column(
children: [
Expanded(
child: Container(
color: Theme.of(context).colorScheme.surfaceContainerHigh,
child: Center(
child: Icon(
Icons.calculate,
size: 50,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
),
Container(
padding: const EdgeInsets.all(10),
color: Theme.of(context).colorScheme.onTertiary,
width: double.infinity,
child: Text(
item['name'].toString(),
textAlign: TextAlign.start,
style: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
),
],
),
),
),
);
}

Widget _knowledgeCarousel(BuildContext context) {
return ListenableBuilder(
listenable: viewModel.fetchKnowledgesCommand,
builder: (context, child) {
if (viewModel.fetchKnowledgesCommand.running) {
return const Center(child: CircularProgressIndicator());
} else if (viewModel.fetchKnowledgesCommand.isError) {
return const Center(child: Text('Erro ao carregar os dados'));
} else if (viewModel.knowledges.isEmpty) {
return const Center(child: Text('Nenhum dado disponível'));
}
final knowledgeItems = viewModel.knowledges;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.symmetric(horizontal: 30.0),
child: Text(
"Áreas de conhecimento",
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 8),
AspectRatio(
aspectRatio: 3 / 1.2,
child: PageView.builder(
controller: PageController(
viewportFraction: 0.5,
initialPage: 0,
),
itemCount: knowledgeItems.length,
itemBuilder: (context, index) {
final item = knowledgeItems[index];
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 5.0),
child: _knowledgecard(context: context, item: item),
);
},
),
),
],
);
},
);
}
}
Loading

0 comments on commit 64414b9

Please sign in to comment.