Skip to content

Commit

Permalink
Merge pull request #98 from karina-klinkeviciute/#6
Browse files Browse the repository at this point in the history
#6 Finished article challenge
  • Loading branch information
karina-klinkeviciute committed Jan 18, 2022
2 parents 35a8902 + 890e2a3 commit 18417e5
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 23 deletions.
3 changes: 2 additions & 1 deletion lib/navigation/app_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ class AppRouter {
create: (context) => ChallengeArticleCubit(
challengesTypeRepository: challengesArticleRepository),
child: ChallengeArticlePage(
uuid: arguments.type_uuid,
type_uuid: arguments.type_uuid,
uuid: arguments.uuid,
),
));

Expand Down
243 changes: 235 additions & 8 deletions lib/pages/challenge/challenge_article/challenge_article_page.dart
Original file line number Diff line number Diff line change
@@ -1,32 +1,259 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:rainbow_challenge/constants/api.dart';
import 'package:rainbow_challenge/services/dio_client.dart';
import 'package:rainbow_challenge/theme/colors.dart';
import 'package:rainbow_challenge/utils/repository/repositories.dart';
import 'cubit/challenge_article_cubit.dart';
import 'package:rainbow_challenge/widgets/widgets.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

// Single challenge page of type Event Participant.
part 'part_info.dart';

class ChallengeArticlePage extends StatelessWidget {
ChallengeArticlePage({Key? key, required this.uuid}) : super(key: key);
class ChallengeArticlePage extends StatefulWidget {
ChallengeArticlePage({Key? key, required this.type_uuid, required this.uuid})
: super(key: key);

final String type_uuid;
final String uuid;

@override
State<StatefulWidget> createState() {
return _ChallengeArticlePageState(type_uuid: type_uuid, uuid: uuid);
}
}

class _ChallengeArticlePageState extends State<ChallengeArticlePage> {
TextEditingController articleDescriptionController = TextEditingController();
TextEditingController articleTitleController = TextEditingController();
TextEditingController articleUrlController = TextEditingController();
final String type_uuid;
final String uuid;

_ChallengeArticlePageState({required this.type_uuid, required this.uuid});

@override
void initState() {
super.initState();
loadData();
}

Future loadData() async {
var joinedChallenge = await BlocProvider.of<ChallengeArticleCubit>(context)
.fetchChallenge(type_uuid: type_uuid, uuid: uuid);

articleDescriptionController.text = joinedChallenge.description ?? "";
articleTitleController.text = joinedChallenge.article_name ?? "";
articleUrlController.text = joinedChallenge.article_url ?? "";
}

@override
Widget build(BuildContext context) {
BlocProvider.of<ChallengeArticleCubit>(context).fetchChallenge(uuid: uuid);
return WrapperMainWidget(
mainArea: SizedBox(
width: MediaQuery.of(context).size.width * 0.8,
child: Column(
children: [
_challengeInfo,
_challengeForm,
getArticleForm(),
],
)));
}

Widget _challengeForm = ElevatedButton(
onPressed: () {},
// child: Text(AppLocalizations.of(context)!.action_join_challenge),
child: Text('To be added here'));
Widget getArticleForm() {
OutlineInputBorder border = OutlineInputBorder(
borderSide: BorderSide(width: 1, color: ThemeColors.primaryColor),
borderRadius: BorderRadius.circular(5),
);

return Column(
children: [
Padding(
padding: EdgeInsets.only(top: 20),
child: TextFormField(
decoration: InputDecoration(
fillColor: Colors.white,
contentPadding: EdgeInsets.symmetric(horizontal: 12),
filled: true,
hintText: "Aprašykite, kaip atlikote užduotį *",
border: border,
disabledBorder: border,
enabledBorder: border,
floatingLabelBehavior: FloatingLabelBehavior.never,
),
autocorrect: false,
controller: articleDescriptionController,
textInputAction: TextInputAction.done,
obscureText: false,
maxLines: 4,
//onChanged: (val) => {articleDescription = val},
)),
Padding(
padding: EdgeInsets.only(top: 10),
child: TextFormField(
decoration: InputDecoration(
fillColor: Colors.white,
contentPadding: EdgeInsets.symmetric(horizontal: 12),
filled: true,
hintText: "Straipsnio pavadinimas *",
border: border,
disabledBorder: border,
enabledBorder: border,
floatingLabelBehavior: FloatingLabelBehavior.never,
),
autocorrect: false,
controller: articleTitleController,
textInputAction: TextInputAction.done,
obscureText: false,
maxLines: 1,
//onChanged: (val) => {articleTitle = val},
)),
Padding(
padding: EdgeInsets.only(top: 10),
child: TextFormField(
keyboardType: TextInputType.url,
decoration: InputDecoration(
fillColor: Colors.white,
contentPadding: EdgeInsets.symmetric(horizontal: 12),
filled: true,
hintText: "Straipsnio nuoroda",
border: border,
disabledBorder: border,
enabledBorder: border,
floatingLabelBehavior: FloatingLabelBehavior.never,
),
autocorrect: false,
controller: articleUrlController,
textInputAction: TextInputAction.done,
obscureText: false,
maxLines: 1,
//onChanged: (val) => {articleUrl = val},
)),
Padding(
padding: EdgeInsets.only(top: 20),
child: ElevatedButton(
onPressed: () {
saveAction(context);
},
child: Text(
"Saugoti ir pateikti vėliau",
style: TextStyle(color: Colors.white),
))),
Padding(
padding: EdgeInsets.only(top: 10),
child: ElevatedButton(
onPressed: () {
completeAction(context);
},
child: Text(
"Pateikti",
style: TextStyle(color: Colors.white),
)))
],
);
}

completeAction(BuildContext context) async {
if (articleTitleController.text == "" ||
articleDescriptionController.text == "") {
await showMessage(context, "Klaida", "Laukai yra privalomi");
return;
}

JoinedChallengesRepository joinedChallengesRepository =
JoinedChallengesRepository(dioClient: DioClient());

List<MapEntry<String, Object>> bodyParams =
List<MapEntry<String, Object>>.empty(growable: true);

bodyParams.add(MapEntry("description", articleDescriptionController.text));
bodyParams.add(MapEntry("article_url", articleUrlController.text));
bodyParams.add(MapEntry("article_name", articleTitleController.text));

var result = await joinedChallengesRepository.completeChallenge(
uuid: uuid,
challengeType: Api().getChallengeTypeSubPath(Api.challengeTypeArticle),
status: "completed",
bodyParams: bodyParams);

if (result != null &&
result["main_joined_challenge"] != null &&
(result["main_joined_challenge"] as Map<String, dynamic>)["status"] ==
"completed") {
await showMessage(context, "Ačiū!",
"Ačiū už atliktą užduotį! Savanoris peržiūrės jūsų atsakymą ir įskaitys vaivorykštes. Apie tai būsite informuoti pranešimų skiltyje.");
Navigator.of(context).pop();
return;
}

if (result != null &&
result["main_joined_challenge"] != null &&
(result["main_joined_challenge"] as Map<String, dynamic>)["status"] ==
"confirmed") {
await showMessage(context, "Ačiū!",
"Ačiū už atliktą užduotį. Jums vaivorykštės įskaičiuotos.");
Navigator.of(context).pop();
return;
}

if (result != null && result["error"] != null) {
await showMessage(context, "Klaida", result["error"]);
return;
}

await showMessage(
context, "Klaida", "Nenumatyta klaida, mėginkite dar kartą");
}

saveAction(BuildContext context) async {
JoinedChallengesRepository joinedChallengesRepository =
JoinedChallengesRepository(dioClient: DioClient());

List<MapEntry<String, Object>> bodyParams =
List<MapEntry<String, Object>>.empty(growable: true);

bodyParams.add(MapEntry("description", articleDescriptionController.text));
bodyParams.add(MapEntry("article_url", articleUrlController.text));
bodyParams.add(MapEntry("article_name", articleTitleController.text));

var result = await joinedChallengesRepository.completeChallenge(
uuid: uuid,
challengeType: Api().getChallengeTypeSubPath(Api.challengeTypeArticle),
status: "joined",
bodyParams: bodyParams);

if (result != null &&
result["main_joined_challenge"] != null &&
(result["main_joined_challenge"] as Map<String, dynamic>)["status"] ==
"joined") {
await showMessage(context, "Ačiū!", "Pakeitimai išsaugoti");
Navigator.of(context).pop();
return;
}

if (result != null && result["error"] != null) {
await showMessage(context, "Klaida", result["error"]);
return;
}

await showMessage(
context, "Klaida", "Nenumatyta klaida, mėginkite dar kartą");
}

Future showMessage(BuildContext context, String title, String message) {
return showDialog<String>(
context: context,
builder: (BuildContext context) => AlertDialog(
title: Text(title),
content: Text(message),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(context, 'OK'),
child: const Text('OK'),
),
],
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ class ChallengeArticleCubit extends Cubit<ChallengeArticleState> {
ChallengeArticleCubit({required this.challengesTypeRepository})
: super(ChallengeArticleInitial());

void fetchChallenge({required String uuid}) {
Timer(Duration(seconds: 1), () {
challengesTypeRepository
.fetchChallenge(uuid: uuid)
.then((challengeTypeItem) {
emit(ChallengeArticleLoaded(challengeTypeItem: challengeTypeItem));
});
});
Future<ChallengeArticle> fetchChallenge(
{required String type_uuid, required String uuid}) async {
var challenge =
await challengesTypeRepository.fetchChallenge(uuid: type_uuid);
var joinedChallenge =
await challengesTypeRepository.fetchJoinedChallenge(uuid: uuid);

emit(ChallengeArticleLoaded(
challengeTypeItem: challenge, challenge: joinedChallenge));
return joinedChallenge;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ class ChallengeArticleInitial extends ChallengeArticleState {}

class ChallengeArticleLoaded extends ChallengeArticleState {
final ChallengeArticle challengeTypeItem;
ChallengeArticleLoaded({required this.challengeTypeItem});
final ChallengeArticle challenge;
ChallengeArticleLoaded(
{required this.challengeTypeItem, required this.challenge});
}
1 change: 1 addition & 0 deletions lib/pages/challenge/challenge_article/part_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Widget _challengeInfo =
padding: const EdgeInsets.symmetric(vertical: 20.0),
child: CircularProgressIndicator(),
));

final challengeTypeItem = (state).challengeTypeItem;
return Column(children: [
ChallengeHeadlineWidget(
Expand Down
6 changes: 6 additions & 0 deletions lib/services/dio_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ class DioClient {
return response.data;
} on DioError catch (e) {
print(e);

if (e.response?.data is Map<String, dynamic>) {
Map<String, dynamic> dataMap = e.response?.data as Map<String, dynamic>;
var errorMessagesList = dataMap.entries.first.value as List<dynamic>;
return {"error": errorMessagesList.first};
}
} on Exception catch (e) {
// Unhandled exception
print(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ part 'challenge_article_class.g.dart';
// explicitToJson lets using nested class Challenge
@JsonSerializable(explicitToJson: true)
class ChallengeArticle {
ChallengeArticle({required this.uuid, required this.main_challenge});
ChallengeArticle(
{required this.uuid,
required this.main_challenge,
required this.description,
required this.article_url,
required this.article_name});

String uuid;
Challenge main_challenge;
String? description;
String? article_url;
String? article_name;

factory ChallengeArticle.fromJson(Map<String, dynamic> json) =>
_$ChallengeArticleFromJson(json);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions lib/utils/model/challenge/challenge_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ class Challenge {
required this.is_joined,
required this.concrete_joined_challenges});

factory Challenge.empty() => Challenge(
uuid: "",
concrete_challenge_uuid: "",
type: "",
name: "",
description: "",
points: 0,
multiple: false,
needs_confirmation: false,
can_be_joined: false,
is_joined: false,
concrete_joined_challenges: List<ConcreteJoinedChallenge>.empty());

factory Challenge.fromJson(Map<String, dynamic> json) =>
_$ChallengeFromJson(json);
Map<String, dynamic> toJson() => _$ChallengeToJson(this);
Expand Down
Loading

0 comments on commit 18417e5

Please sign in to comment.