Skip to content

Commit

Permalink
Merge pull request #242 from aeecleclair/recommendation
Browse files Browse the repository at this point in the history
Recommendation
  • Loading branch information
guillaumetavernier authored Mar 4, 2024
2 parents 0d8b573 + 3e6dfab commit 511e307
Show file tree
Hide file tree
Showing 21 changed files with 1,030 additions and 2 deletions.
59 changes: 59 additions & 0 deletions lib/recommendation/class/recommendation.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
class Recommendation {
final String? id;
final DateTime? creation;
final String title;
final String? code;
final String summary;
final String description;

Recommendation({
this.id,
this.creation,
required this.title,
required this.code,
required this.summary,
required this.description,
});

Recommendation.fromJson(Map<String, dynamic> json)
: id = json["id"],
creation = DateTime.parse(json["creation"]),
title = json["title"],
code = json["code"],
summary = json["summary"],
description = json["description"];

Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data["title"] = title;
data["code"] = code;
data["summary"] = summary;
data["description"] = description;
return data;
}

Recommendation copyWith({id, creation, title, code, summary, description}) {
return Recommendation(
id: id ?? this.id,
creation: creation ?? this.creation,
title: title ?? this.title,
code: code ?? this.code,
summary: summary ?? this.summary,
description: description ?? this.description,
);
}

static Recommendation empty() {
return Recommendation(
title: "",
code: null,
summary: "",
description: "",
);
}

@override
String toString() {
return 'Recommendation{id: $id, creation: $creation, title: $title, code: $code, summary: $summary, description: $description}';
}
}
11 changes: 11 additions & 0 deletions lib/recommendation/providers/is_recommendation_admin_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:myecl/user/providers/user_provider.dart';

final isRecommendationAdminProvider = StateProvider<bool>(
(ref) {
final me = ref.watch(userProvider);
return me.groups
.map((e) => e.id)
.contains("53a669d6-84b1-4352-8d7c-421c1fbd9c6a");
},
);
57 changes: 57 additions & 0 deletions lib/recommendation/providers/recommendation_list_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:myecl/recommendation/class/recommendation.dart';
import 'package:myecl/recommendation/repositories/recommendation_repository.dart';
import 'package:myecl/tools/providers/list_notifier.dart';
import 'package:myecl/tools/token_expire_wrapper.dart';

class RecommendationListNotifier extends ListNotifier<Recommendation> {
final RecommendationRepository recommendationRepository;

RecommendationListNotifier({required this.recommendationRepository})
: super(const AsyncValue.loading());

Future<AsyncValue<List<Recommendation>>> loadRecommendation() async {
return await loadList(recommendationRepository.getRecommendationList);
}

Future<bool> addRecommendation(Recommendation recommendation) async {
return await add(
recommendationRepository.createRecommendation, recommendation);
}

Future<bool> updateRecommendation(Recommendation recommendation) async {
return await update(
recommendationRepository.updateRecommendation,
(recommendations, recommendation) => recommendations
..[recommendations.indexWhere((r) => r.id == recommendation.id)] =
recommendation,
recommendation,
);
}

Future<bool> deleteRecommendation(Recommendation recommendation) async {
return await delete(
recommendationRepository.deleteRecommendation,
(recommendations, recommendation) =>
recommendations..removeWhere((r) => r.id == recommendation.id),
recommendation.id!,
recommendation,
);
}
}

final recommendationListProvider = StateNotifierProvider<
RecommendationListNotifier, AsyncValue<List<Recommendation>>>(
(ref) {
final recommendatioRepository = ref.watch(recommendationRepositoryProvider);
final provider = RecommendationListNotifier(
recommendationRepository: recommendatioRepository);
tokenExpireWrapperAuth(
ref,
() async {
await provider.loadRecommendation();
},
);
return provider;
},
);
35 changes: 35 additions & 0 deletions lib/recommendation/providers/recommendation_logo_map_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:myecl/recommendation/class/recommendation.dart';
import 'package:myecl/recommendation/providers/recommendation_list_provider.dart';
import 'package:myecl/tools/providers/map_provider.dart';
import 'package:myecl/tools/token_expire_wrapper.dart';

class RecommendationLogoMapNotifier extends MapNotifier<Recommendation, Image> {
RecommendationLogoMapNotifier() : super();
}

final recommendationLogoMapProvider = StateNotifierProvider<
RecommendationLogoMapNotifier,
AsyncValue<Map<Recommendation, AsyncValue<List<Image>>?>>>(
(ref) {
RecommendationLogoMapNotifier recommendationLogoMapNotifier =
RecommendationLogoMapNotifier();
tokenExpireWrapperAuth(
ref,
() async {
ref.watch(recommendationListProvider).maybeWhen(
data: (data) {
recommendationLogoMapNotifier.loadTList(data);
return recommendationLogoMapNotifier;
},
orElse: () {
recommendationLogoMapNotifier.loadTList([]);
return recommendationLogoMapNotifier;
},
);
},
);
return recommendationLogoMapNotifier;
},
);
30 changes: 30 additions & 0 deletions lib/recommendation/providers/recommendation_logo_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:myecl/recommendation/repositories/recommendation_logo_repository.dart';
import 'package:myecl/tools/providers/single_notifier.dart';

class RecommendationLogoNotifier extends SingleNotifier<Image> {
final RecommendationLogoRepository recommendationLogoRepository;
RecommendationLogoNotifier({required this.recommendationLogoRepository})
: super(const AsyncValue.loading());

Future<Image> getRecommendationLogo(String id) async {
return await recommendationLogoRepository.getRecommendationLogo(id);
}

Future<Image> updateRecommendationLogo(String id, Uint8List bytes) async {
return await recommendationLogoRepository.addRecommendationLogo(bytes, id);
}
}

final recommendationLogoProvider =
StateNotifierProvider<RecommendationLogoNotifier, AsyncValue<Image>>(
(ref) {
final recommendationLogoRepository =
ref.watch(recommendationLogoRepositoryProvider);
return RecommendationLogoNotifier(
recommendationLogoRepository: recommendationLogoRepository);
},
);
17 changes: 17 additions & 0 deletions lib/recommendation/providers/recommendation_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:myecl/recommendation/class/recommendation.dart';

class RecommendationNotifier extends StateNotifier<Recommendation> {
RecommendationNotifier() : super(Recommendation.empty());

void setRecommendation(Recommendation r) {
state = r;
}
}

final recommendationProvider =
StateNotifierProvider<RecommendationNotifier, Recommendation>(
(ref) {
return RecommendationNotifier();
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:myecl/auth/providers/openid_provider.dart';
import 'package:myecl/tools/repository/logo_repository.dart';

class RecommendationLogoRepository extends LogoRepository {
@override
// ignore: overridden_fields
final ext = "recommendation/recommendations";

Future<Image> getRecommendationLogo(String id) async {
final uint8List = await getLogo("", suffix: "/$id/picture");
return Image.memory(uint8List);
}

Future<Image> addRecommendationLogo(Uint8List bytes, String id) async {
final uint8List = await addLogo(bytes, "", suffix: "/$id/picture");
return Image.memory(uint8List);
}
}

final recommendationLogoRepositoryProvider =
Provider<RecommendationLogoRepository>(
(ref) {
final token = ref.watch(tokenProvider);
return RecommendationLogoRepository()..setToken(token);
},
);
35 changes: 35 additions & 0 deletions lib/recommendation/repositories/recommendation_repository.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:myecl/auth/providers/openid_provider.dart';
import 'package:myecl/recommendation/class/recommendation.dart';
import 'package:myecl/tools/repository/repository.dart';

class RecommendationRepository extends Repository {
@override
// ignore: overridden_fields
final ext = 'recommendation/recommendations';

Future<List<Recommendation>> getRecommendationList() async {
return List<Recommendation>.from(
(await getList()).map((x) => Recommendation.fromJson(x)));
}

Future<Recommendation> createRecommendation(
Recommendation recommendation) async {
return Recommendation.fromJson(await create(recommendation.toJson()));
}

Future<bool> updateRecommendation(Recommendation recommendation) async {
return await update(recommendation.toJson(), "/${recommendation.id}");
}

Future<bool> deleteRecommendation(String recommendationId) async {
return await delete("/$recommendationId");
}
}

final recommendationRepositoryProvider = Provider<RecommendationRepository>(
(ref) {
final token = ref.watch(tokenProvider);
return RecommendationRepository()..setToken(token);
},
);
57 changes: 57 additions & 0 deletions lib/recommendation/router.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:either_dart/either.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:heroicons/heroicons.dart';
import 'package:myecl/drawer/class/module.dart';
import 'package:myecl/recommendation/providers/is_recommendation_admin_provider.dart';
import 'package:myecl/recommendation/ui/pages/main_page.dart'
deferred as main_page;
import 'package:myecl/recommendation/ui/pages/information_page.dart'
deferred as information_page;
import 'package:myecl/recommendation/ui/pages/add_edit_page.dart'
deferred as add_edit_page;
import 'package:myecl/tools/middlewares/admin_middleware.dart';
import 'package:myecl/tools/middlewares/authenticated_middleware.dart';
import 'package:myecl/tools/middlewares/deferred_middleware.dart';
import 'package:qlevar_router/qlevar_router.dart';

class RecommendationRouter {
final ProviderRef ref;

static const String root = '/recommendation';
static const String information = '/information';
static const String addEdit = '/add_edit';
static final Module module = Module(
name: "Bons plans",
icon: const Left(HeroIcons.newspaper),
root: RecommendationRouter.root,
selected: false,
);

RecommendationRouter(this.ref);

QRoute route() => QRoute(
path: RecommendationRouter.root,
builder: () => main_page.RecommendationMainPage(),
middleware: [
AuthenticatedMiddleware(ref),
DeferredLoadingMiddleware(main_page.loadLibrary),
],
children: [
QRoute(
path: information,
builder: () => information_page.InformationRecommendationPage(),
middleware: [
DeferredLoadingMiddleware(information_page.loadLibrary)
],
),
QRoute(
path: addEdit,
builder: () => add_edit_page.AddEditRecommendationPage(),
middleware: [
AdminMiddleware(ref, isRecommendationAdminProvider),
DeferredLoadingMiddleware(add_edit_page.loadLibrary)
],
),
],
);
}
25 changes: 25 additions & 0 deletions lib/recommendation/tools/constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class RecommendationTextConstants {
static const String recommendation = "Bons plans";
static const String title = "Titre";
static const String logo = "Logo";
static const String code = "Code";
static const String summary = "Court résumé";
static const String description = "Description";
static const String add = "Ajouter";
static const String edit = "Modifier";
static const String delete = "Supprimer";
static const String addImage = "Veuillez ajouter une image";
static const String addedRecommendation = "Bon plan ajouté";
static const String editedRecommendation = "Bon plan modifié";
static const String deleteRecommendationConfirmation =
"Êtes-vous sûr de vouloir supprimer ce bon plan ?";
static const String deleteRecommendation = "Suppresion";
static const String deletingRecommendationError =
"Erreur lors de la suppression";
static const String deletedRecommendation = "Bon plan supprimé";
static const String incorrectOrMissingFields =
'Champs incorrects ou manquants';
static const String editingError = "Échec de la modification";
static const String addingError = "Échec de l'ajout";
static const String copiedCode = "Code de réduction copié";
}
Loading

0 comments on commit 511e307

Please sign in to comment.