Browse Source

added update

master
TheNils 3 months ago
parent
commit
0142ffbe46
  1. 18
      lib/api/api.dart
  2. 38
      lib/api/schema.dart
  3. 3
      lib/lang/en.dart
  4. 3
      lib/lang/fr.dart
  5. 2
      lib/main.dart
  6. 80
      lib/store/projects.dart
  7. 0
      lib/store/schema.json
  8. 99
      lib/store/user.dart
  9. 25
      lib/views/account.dart
  10. 54
      lib/views/accountForm.dart
  11. 7
      pubspec.lock
  12. 2
      pubspec.yaml

18
lib/api/api.dart

@ -36,9 +36,9 @@ class Api {
Future<Map<dynamic, dynamic>> handleResponse(
Future<dynamic> response,
String path,
Map<String, dynamic> body,
Map<dynamic, dynamic> body,
int tryCount,
Function(String path, Map<String, dynamic> body, int tryCount)
Function(String path, Map<dynamic, dynamic> body, int tryCount)
callback) async {
return await response.then((res) {
var json = jsonDecode(res.body);
@ -61,7 +61,7 @@ class Api {
});
}
Future<Map<String, dynamic>> post(String path, Map<String, dynamic> body,
Future<Map<dynamic, dynamic>> post(String path, Map<dynamic, dynamic> body,
[int tryCount = 1]) async {
await refreshJwt();
@ -70,17 +70,19 @@ class Api {
return await handleResponse(res, path, body, tryCount, post);
}
Future<Map<String, dynamic>> patch(String path, Map<String, dynamic> body,
Future<Map<dynamic, dynamic>> patch(String path, Map<dynamic, dynamic> body,
[int tryCount = 1]) async {
print("api patch");
await refreshJwt();
print("api after jwt");
var res = client.patch('${globals.apiUrl}$path',
headers: this.apiHeaders, body: body);
headers: this.apiHeaders, body: jsonEncode(body));
return await handleResponse(res, path, body, tryCount, patch);
}
Future<Map<dynamic, dynamic>> get(String path,
[Map<String, dynamic> body = const {}, int tryCount = 1]) async {
[Map<dynamic, dynamic> body = const {}, int tryCount = 1]) async {
await refreshJwt();
var res = http.get(
@ -90,7 +92,7 @@ class Api {
return await handleResponse(res, path, body, tryCount, get);
}
Future<Map<String, dynamic>> put(String path, Map<String, dynamic> body,
Future<Map<dynamic, dynamic>> put(String path, Map<dynamic, dynamic> body,
[int tryCount = 1]) async {
await refreshJwt();
@ -99,7 +101,7 @@ class Api {
return await handleResponse(res, path, body, tryCount, put);
}
Future<Map<String, dynamic>> delete(String path, Map<String, dynamic> body,
Future<Map<dynamic, dynamic>> delete(String path, Map<dynamic, dynamic> body,
[int tryCount = 1]) async {
await refreshJwt();

38
lib/api/schema.dart

@ -0,0 +1,38 @@
Map<dynamic, dynamic> schema = {
"projects": {
"project_id": {
"collection": "project",
"kind": "M2M",
"customers": {
"directu_users_id": {"collection": "directus_users", "kind": "M2M"}
},
"agencies": {
"agency_id": {"collection": "agency", "kind": "M2M"}
},
"steps": {
"collection": "steps",
"kind": "O2M",
"repports": {"collection": "repport", "kind": "O2M"}
}
}
},
"agencies": {
"agency_id": {
"collection": "agency",
"employees": {"collection": "directus_users"},
"projects": {
"project_id": {
"collection": "project",
"kind": "M2M",
"customers": {"collection": "directus_users", "kind": "M2M"},
//"agencies": {"collection": "agency", "kind": "M2M"},
"steps": {
"collection": "steps",
"kind": "O2M",
"repports": {"collection": "repport", "kind": "O2M"}
}
}
}
}
}
};

3
lib/lang/en.dart

@ -4,4 +4,7 @@ Map<String, String> en = {
'signup': 'Sign up',
'my-account': 'My Account',
'my-projects': 'My Projects',
'edit': 'Edit',
'save': 'Save',
'first-name': 'First name',
};

3
lib/lang/fr.dart

@ -4,4 +4,7 @@ Map<String, String> fr = {
'signup': 'Créer un compte',
'my-account': 'Mon compte',
'my-projects': 'Mes Projets',
'edit': 'Modifier',
'save': 'Sauvegarder',
'first-name': 'Prénom',
};

2
lib/main.dart

@ -9,6 +9,7 @@ import 'package:youtribe_lib/lang/fr.dart';
import 'package:youtribe_lib/views/login/login.dart';
import 'package:youtribe_lib/views/account.dart';
import 'package:youtribe_lib/views/accountForm.dart';
// translation
class Messages extends Translations {
@ -35,6 +36,7 @@ class NavMap extends StatelessWidget {
routes: {
'/': (context) => Login(),
'/account': (context) => Account(),
'/account_form': (context) => AccountForm(),
},
);
}

80
lib/store/projects.dart

@ -0,0 +1,80 @@
import 'dart:convert';
import 'dart:developer';
import 'package:get/state_manager.dart';
import 'package:youtribe_lib/api/api.dart';
import 'package:localstorage/localstorage.dart';
class Projects extends GetxController {
final _collection = 'project';
final _fields = '''
project.*,
project.agencies.agency_id,
project.customers.customer_id,
'''
.trim()
.replaceAll(" ", "");
var _filters = "";
final _api = Api();
final _items = Rx<List<dynamic>>().obs;
final isLoading = false.obs;
var _localStorage;
get items => _items().value;
set items(payload) {
_items(Rx(payload));
_localStorage.setItem(_collection, jsonEncode(items));
}
@override
void onInit() async {
_localStorage = new LocalStorage('$_collection-store');
await _localStorage.ready;
var localItems = await _localStorage.getItem('items');
if (localItems != null) {
items = jsonDecode(localItems);
fetch();
}
super.onInit();
}
Future<bool> fetch() async {
var res = await _api.get('/$_collection?$_fields&$_filters');
if (!res.containsKey('error')) {
items = res;
_localStorage.setItem(_collection, jsonEncode(items));
return true;
} else {
return false;
}
}
Future<bool> patch(String collection, Map<dynamic, dynamic> item) async {
if (!item.containsKey('id')) {
log('id needed', level: 3);
return false;
}
var itemId = item['id'];
item.remove('id');
var res = await _api.patch('/$collection/$itemId', item);
if (!res.containsKey('error')) {
int index = items.indexWhere((element) => element['id'] == item['id']);
items[index] = {...items[index], ...item};
return true;
} else {
return false;
}
}
// Future<bool> add(String collection, Map<dynamic, dynamic> item) async {}
// Future<bool> remove(String collection, {String id, int index}) async {}
}

0
lib/store/projectStore.dart → lib/store/schema.json

99
lib/store/user.dart

@ -1,24 +1,30 @@
import 'dart:convert';
import 'package:deeply/deeply.dart';
import 'package:get/state_manager.dart';
import 'package:youtribe_lib/api/api.dart';
import 'package:localstorage/localstorage.dart';
import 'package:youtribe_lib/api/schema.dart';
class UserController extends GetxController {
final localStorage = new LocalStorage('user-store');
final api = Api();
final _localStorage = new LocalStorage('user-store');
final _api = Api();
final _user = Rx<Map<dynamic, dynamic>>({}).obs;
Map<dynamic, dynamic> patchStatuses;
get user => _user().value;
set user(payload) {
// patch(payload);
_user(Rx({..._user().value, ...payload}));
localStorage.setItem('user', jsonEncode(user));
_localStorage.setItem('user', jsonEncode(user));
}
get projects => _user().value['projects'].map((p) => p['project_id']);
Future<Map<dynamic, dynamic>> authenticate(
Map<String, String> payload) async {
var res = await api.authenticate(payload);
var res = await _api.authenticate(payload);
if (!res.containsKey('error')) {
user = res;
@ -29,35 +35,100 @@ class UserController extends GetxController {
@override
void onInit() async {
await localStorage.ready;
var localUser = await localStorage.getItem('user');
await _localStorage.ready;
var localUser = await _localStorage.getItem('user');
if (localUser != null) {
user = jsonDecode(localUser);
var canResume =
await api.resumeSession(user['access_token'], user['refresh_token']);
await _api.resumeSession(user['access_token'], user['refresh_token']);
if (canResume) {
user = {'refresh_token': api.credentials['refreshToken']};
user = {'refresh_token': _api.credentials['refreshToken']};
fetch();
} else {
await this.localStorage.deleteItem('user');
await this._localStorage.deleteItem('user');
}
}
super.onInit();
}
Future<Map<dynamic, dynamic>> fetch() async {
var res = await api.get('/users/me');
var res = await _api.get('''
/users/me?fields=*,
agencies.agency_id.*,
agencies.agency_id.projects.project_id.*,
agencies.agency_id.projects.project_id.customers.*,
agencies.agency_id.projects.project_id.steps.*,
agencies.agency_id.projects.project_id.steps.repports.*,
projects.project_id.*,
projects.project_id.agencies.agency_id.*,
projects.project_id.initial_shots.*,
projects.project_id.steps.*,
projects.project_id.steps.repports.*
'''
.trim()
.replaceAll("\n", "")
.replaceAll(" ", ""));
if (!res.containsKey('error')) {
user = res;
}
return user;
}
void changeUser() {
user = {'first_name': 'testeur', 'last_name': 'testeur last name'};
Future<bool> patch(Map<dynamic, dynamic> item, {String collection}) async {
print("userController patch");
var id = item.containsKey("id") ? item["id"] : null;
item.remove("id");
var computedPath =
collection != null ? "/items/$collection/$id" : "/users/me";
var res = await _api.patch(computedPath, item);
if (!res.containsKey('error')) {
_updateCollection(collection, {
...item,
...{"id": id}
});
return true;
} else {
return false;
}
}
// Future<
void _updateCollection(String collection, Map<dynamic, dynamic> item,
[List<String> startPath]) {
var currentPath = startPath != null ? startPath : [];
var subSchema = schema;
currentPath.forEach((value) {
subSchema = subSchema[value];
});
List<String> reserved = ["collection", "kind"];
subSchema.forEach((key, value) {
if (!reserved.contains(key) && value is Map) {
_updateCollection(collection, item, [
...currentPath,
...[key]
]);
if (value.containsKey("collection")) {
if (value["collection"] == collection) {
updateDeeply(currentPath, _user().value, (value) {
if (value is List) {
var index = value
.indexWhere((element) => element[key]["id"] == item["id"]);
value[index][key] = {...value[index][key], ...item};
} else if (value != null) {
value = {...value, ...item};
}
});
}
}
}
});
}
}

25
lib/views/account.dart

@ -5,33 +5,24 @@ import 'package:youtribe_lib/store/user.dart';
class Account extends StatelessWidget {
final UserController userController = Get.put(UserController());
void test() {
userController.changeUser();
print(userController.user());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Account'.tr),
title: Text('my-acount'.tr),
),
body: Center(
child: Obx(
() => (Column(
children: [
Text('${userController.user['id']}'),
Text('${userController.user['first_name']}'),
Text('${userController.user['last_name']}'),
Text('${userController.user['email']}'),
// Obx(() => Text('${userController.user().lastName}')),
// Obx(() => Text('${userController.user().email}')),
// Obx(() => Text('${userController.user().avatar}')),
Text('my-projects'.tr),
Text('id: ${userController.user['id']}'),
Text('first name: ${userController.user['first_name']}'),
Text('last name: ${userController.user['last_name']}'),
Text('email: ${userController.user['email']}'),
OutlinedButton(
onPressed: test,
child: Text('test button'),
)
onPressed: () => Get.toNamed('/account_form'),
child: Text('edit'.tr),
),
],
)),
),

54
lib/views/accountForm.dart

@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:youtribe_lib/store/user.dart';
class AccountForm extends StatefulWidget {
@override
AccountFormState createState() => AccountFormState();
}
class AccountFormState extends State<AccountForm> {
final userController = Get.put(UserController());
final _formKey = GlobalKey<FormState>();
String email;
String firstName;
String lastName;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('my-account'.tr),
),
body: Center(
child: FractionallySizedBox(
widthFactor: 0.5,
child: Obx(
() => (Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('my-account'.tr),
TextFormField(
decoration: InputDecoration(labelText: 'first-name'.tr),
initialValue: userController.user['first_name'],
onChanged: (value) => firstName = value,
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () => userController.patch(
{"id": 2, "title": "bbb"},
collection: "agency"),
// userController.patch({'first_name': firstName}),
child: Text('save'.tr))
],
),
)),
),
),
));
}
}

7
pubspec.lock

@ -64,6 +64,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
deeply:
dependency: "direct main"
description:
name: deeply
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0+1"
fake_async:
dependency: transitive
description:

2
pubspec.yaml

@ -28,7 +28,7 @@ dependencies:
flutter_map: any # or the latest version on Pub
flutter_map_marker_popup: any
localstorage: ^3.0.6+9
deeply: ^1.1.0+1
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.3

Loading…
Cancel
Save