@coorpacademy/app-review 0.0.15 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/actions/courses.d.ts +7 -0
- package/es/actions/courses.d.ts.map +1 -0
- package/es/actions/courses.js +5 -0
- package/es/actions/index.d.ts +6 -0
- package/es/actions/index.d.ts.map +1 -1
- package/es/actions/index.js +2 -0
- package/es/actions/navigation.d.ts +11 -4
- package/es/actions/navigation.d.ts.map +1 -1
- package/es/actions/navigation.js +5 -0
- package/es/actions/token.d.ts +7 -0
- package/es/actions/token.d.ts.map +1 -0
- package/es/actions/token.js +5 -0
- package/es/components/__tmp-backup-vues-mobile/revision-home.stories.d.ts +0 -1
- package/es/components/__tmp-backup-vues-mobile/revision-home.stories.js +14 -14
- package/es/configure-store.d.ts +11 -3
- package/es/configure-store.d.ts.map +1 -1
- package/es/configure-store.js +4 -2
- package/es/index.d.ts +9 -3
- package/es/index.d.ts.map +1 -1
- package/es/index.js +4 -4
- package/es/middlewares/on-start-app.d.ts +7 -0
- package/es/middlewares/on-start-app.d.ts.map +1 -0
- package/es/middlewares/on-start-app.js +17 -0
- package/es/reducers/courses.d.ts +6 -0
- package/es/reducers/courses.d.ts.map +1 -0
- package/es/reducers/courses.js +14 -0
- package/es/reducers/index.d.ts +2 -0
- package/es/reducers/index.d.ts.map +1 -1
- package/es/reducers/index.js +5 -1
- package/es/reducers/navigation.d.ts +2 -2
- package/es/reducers/navigation.d.ts.map +1 -1
- package/es/reducers/navigation.js +3 -0
- package/es/reducers/token.d.ts +7 -0
- package/es/reducers/token.d.ts.map +1 -0
- package/es/reducers/token.js +16 -0
- package/es/services/fetch-demo.d.ts +12 -0
- package/es/services/fetch-demo.d.ts.map +1 -0
- package/es/services/fetch-demo.js +26 -0
- package/es/services/fetch-demo.test.d.ts +2 -0
- package/es/services/fetch-demo.test.d.ts.map +1 -0
- package/es/services/fetch-demo.test.js +12 -0
- package/es/services/fetch-responses.d.ts +20 -0
- package/es/services/fetch-responses.d.ts.map +1 -0
- package/es/services/fetch-responses.js +33 -0
- package/es/services/fetch.mocks.d.ts +10 -0
- package/es/services/fetch.mocks.d.ts.map +1 -0
- package/es/services/fetch.mocks.js +12 -0
- package/lib/actions/courses.d.ts +7 -0
- package/lib/actions/courses.d.ts.map +1 -0
- package/lib/actions/courses.js +9 -0
- package/lib/actions/index.d.ts +6 -0
- package/lib/actions/index.d.ts.map +1 -1
- package/lib/actions/index.js +2 -0
- package/lib/actions/navigation.d.ts +11 -4
- package/lib/actions/navigation.d.ts.map +1 -1
- package/lib/actions/navigation.js +7 -1
- package/lib/actions/token.d.ts +7 -0
- package/lib/actions/token.d.ts.map +1 -0
- package/lib/actions/token.js +9 -0
- package/lib/components/__tmp-backup-vues-mobile/revision-home.stories.d.ts +0 -1
- package/lib/components/__tmp-backup-vues-mobile/revision-home.stories.js +14 -16
- package/lib/configure-store.d.ts +11 -3
- package/lib/configure-store.d.ts.map +1 -1
- package/lib/configure-store.js +4 -2
- package/lib/index.d.ts +9 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -3
- package/lib/middlewares/on-start-app.d.ts +7 -0
- package/lib/middlewares/on-start-app.d.ts.map +1 -0
- package/lib/middlewares/on-start-app.js +22 -0
- package/lib/reducers/courses.d.ts +6 -0
- package/lib/reducers/courses.d.ts.map +1 -0
- package/lib/reducers/courses.js +27 -0
- package/lib/reducers/index.d.ts +2 -0
- package/lib/reducers/index.d.ts.map +1 -1
- package/lib/reducers/index.js +5 -1
- package/lib/reducers/navigation.d.ts +2 -2
- package/lib/reducers/navigation.d.ts.map +1 -1
- package/lib/reducers/navigation.js +3 -0
- package/lib/reducers/token.d.ts +7 -0
- package/lib/reducers/token.d.ts.map +1 -0
- package/lib/reducers/token.js +21 -0
- package/lib/services/fetch-demo.d.ts +12 -0
- package/lib/services/fetch-demo.d.ts.map +1 -0
- package/lib/services/fetch-demo.js +76 -0
- package/lib/services/fetch-demo.test.d.ts +2 -0
- package/lib/services/fetch-demo.test.d.ts.map +1 -0
- package/lib/services/fetch-demo.test.js +59 -0
- package/lib/services/fetch-responses.d.ts +20 -0
- package/lib/services/fetch-responses.d.ts.map +1 -0
- package/lib/services/fetch-responses.js +118 -0
- package/lib/services/fetch.mocks.d.ts +10 -0
- package/lib/services/fetch.mocks.d.ts.map +1 -0
- package/lib/services/fetch.mocks.js +31 -0
- package/package.json +13 -8
- package/readme.md +38 -1
- package/src/actions/courses.ts +11 -0
- package/src/actions/index.ts +8 -0
- package/src/actions/navigation.ts +16 -4
- package/src/actions/token.ts +11 -0
- package/src/components/__tmp-backup-vues-mobile/revision-home.stories.tsx +14 -14
- package/src/configure-store.ts +15 -2
- package/src/index.tsx +12 -3
- package/src/middlewares/on-start-app.ts +30 -0
- package/src/reducers/courses.ts +22 -0
- package/src/reducers/index.ts +6 -1
- package/src/reducers/navigation.ts +11 -3
- package/src/reducers/token.ts +26 -0
- package/src/services/fetch-demo.test.ts +16 -0
- package/src/services/fetch-demo.ts +55 -0
- package/src/services/fetch-responses.ts +53 -0
- package/src/services/fetch.mocks.ts +26 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
20
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
21
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
22
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
23
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
27
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
28
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
29
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
30
|
+
function step(op) {
|
|
31
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
32
|
+
while (_) try {
|
|
33
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
34
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
35
|
+
switch (op[0]) {
|
|
36
|
+
case 0: case 1: t = op; break;
|
|
37
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
38
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
39
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
40
|
+
default:
|
|
41
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
42
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
43
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
44
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
45
|
+
if (t[2]) _.ops.pop();
|
|
46
|
+
_.trys.pop(); continue;
|
|
47
|
+
}
|
|
48
|
+
op = body.call(thisArg, _);
|
|
49
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
50
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
+
exports.toVoid = exports.toText = exports.toJSON = exports.ResponseError = void 0;
|
|
55
|
+
var ResponseError = /** @class */ (function (_super) {
|
|
56
|
+
__extends(ResponseError, _super);
|
|
57
|
+
function ResponseError(status, statusText, body) {
|
|
58
|
+
if (body === void 0) { body = ''; }
|
|
59
|
+
var _this = _super.call(this, "".concat(statusText, " ").concat(body).trim()) || this;
|
|
60
|
+
_this.name = 'ResponseError';
|
|
61
|
+
_this.statusCode = status;
|
|
62
|
+
return _this;
|
|
63
|
+
}
|
|
64
|
+
return ResponseError;
|
|
65
|
+
}(Error));
|
|
66
|
+
exports.ResponseError = ResponseError;
|
|
67
|
+
var toJSON = function (response) { return __awaiter(void 0, void 0, void 0, function () {
|
|
68
|
+
var body, err_1;
|
|
69
|
+
return __generator(this, function (_a) {
|
|
70
|
+
switch (_a.label) {
|
|
71
|
+
case 0:
|
|
72
|
+
if (!!response.ok) return [3 /*break*/, 2];
|
|
73
|
+
return [4 /*yield*/, response.text()];
|
|
74
|
+
case 1:
|
|
75
|
+
body = _a.sent();
|
|
76
|
+
throw new ResponseError(response.status, response.statusText, body);
|
|
77
|
+
case 2:
|
|
78
|
+
_a.trys.push([2, 4, , 5]);
|
|
79
|
+
return [4 /*yield*/, response.json()];
|
|
80
|
+
case 3: return [2 /*return*/, _a.sent()];
|
|
81
|
+
case 4:
|
|
82
|
+
err_1 = _a.sent();
|
|
83
|
+
throw new ResponseError(response.status, response.statusText);
|
|
84
|
+
case 5: return [2 /*return*/];
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}); };
|
|
88
|
+
exports.toJSON = toJSON;
|
|
89
|
+
var toText = function (response) { return __awaiter(void 0, void 0, void 0, function () {
|
|
90
|
+
var body;
|
|
91
|
+
return __generator(this, function (_a) {
|
|
92
|
+
switch (_a.label) {
|
|
93
|
+
case 0: return [4 /*yield*/, response.text()];
|
|
94
|
+
case 1:
|
|
95
|
+
body = _a.sent();
|
|
96
|
+
if (!response.ok) {
|
|
97
|
+
throw new ResponseError(response.status, response.statusText, body);
|
|
98
|
+
}
|
|
99
|
+
return [2 /*return*/, body];
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}); };
|
|
103
|
+
exports.toText = toText;
|
|
104
|
+
var toVoid = function (response) { return __awaiter(void 0, void 0, void 0, function () {
|
|
105
|
+
var body;
|
|
106
|
+
return __generator(this, function (_a) {
|
|
107
|
+
switch (_a.label) {
|
|
108
|
+
case 0:
|
|
109
|
+
if (!!response.ok) return [3 /*break*/, 2];
|
|
110
|
+
return [4 /*yield*/, response.text()];
|
|
111
|
+
case 1:
|
|
112
|
+
body = _a.sent();
|
|
113
|
+
throw new ResponseError(response.status, response.statusText, body);
|
|
114
|
+
case 2: return [2 /*return*/];
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}); };
|
|
118
|
+
exports.toVoid = toVoid;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Response } from './fetch-responses';
|
|
2
|
+
export declare const toResponse: (status: number, statusText: string, body: string) => Promise<Response>;
|
|
3
|
+
declare type FetchFunction = () => Promise<Response>;
|
|
4
|
+
export declare const okJSONResponse: (body: unknown) => FetchFunction;
|
|
5
|
+
export declare const internalServerErrorJSONResponse: (body: unknown) => FetchFunction;
|
|
6
|
+
export declare const notFoundJSONResponse: (body: unknown) => FetchFunction;
|
|
7
|
+
export declare const okTextResponse: (body: string) => FetchFunction;
|
|
8
|
+
export declare const internalServerErrorTextResponse: (body: string) => FetchFunction;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=fetch.mocks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.mocks.d.ts","sourceRoot":"","sources":["../../src/services/fetch.mocks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAE3C,eAAO,MAAM,UAAU,WAAY,MAAM,cAAc,MAAM,QAAQ,MAAM,KAAG,QAAQ,QAAQ,CAO1F,CAAC;AAEL,aAAK,aAAa,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE7C,eAAO,MAAM,cAAc,SAAU,OAAO,KAAG,aACF,CAAC;AAE9C,eAAO,MAAM,+BAA+B,SAAU,OAAO,KAAG,aACF,CAAC;AAE/D,eAAO,MAAM,oBAAoB,SAAU,OAAO,KAAG,aACD,CAAC;AAErD,eAAO,MAAM,cAAc,SAAU,MAAM,KAAG,aAAkD,CAAC;AAEjG,eAAO,MAAM,+BAA+B,SAAU,MAAM,KAAG,aACjB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.internalServerErrorTextResponse = exports.okTextResponse = exports.notFoundJSONResponse = exports.internalServerErrorJSONResponse = exports.okJSONResponse = exports.toResponse = void 0;
|
|
4
|
+
var toResponse = function (status, statusText, body) {
|
|
5
|
+
return Promise.resolve({
|
|
6
|
+
ok: status < 400,
|
|
7
|
+
status: status,
|
|
8
|
+
statusText: statusText,
|
|
9
|
+
json: function () { return Promise.resolve(body).then(JSON.parse); },
|
|
10
|
+
text: function () { return Promise.resolve(body); }
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
exports.toResponse = toResponse;
|
|
14
|
+
var okJSONResponse = function (body) { return function () {
|
|
15
|
+
return (0, exports.toResponse)(200, 'OK', JSON.stringify(body));
|
|
16
|
+
}; };
|
|
17
|
+
exports.okJSONResponse = okJSONResponse;
|
|
18
|
+
var internalServerErrorJSONResponse = function (body) { return function () {
|
|
19
|
+
return (0, exports.toResponse)(500, 'InternalServerError', JSON.stringify(body));
|
|
20
|
+
}; };
|
|
21
|
+
exports.internalServerErrorJSONResponse = internalServerErrorJSONResponse;
|
|
22
|
+
var notFoundJSONResponse = function (body) { return function () {
|
|
23
|
+
return (0, exports.toResponse)(404, 'Not Found', JSON.stringify(body));
|
|
24
|
+
}; };
|
|
25
|
+
exports.notFoundJSONResponse = notFoundJSONResponse;
|
|
26
|
+
var okTextResponse = function (body) { return function () { return (0, exports.toResponse)(200, 'OK', body); }; };
|
|
27
|
+
exports.okTextResponse = okTextResponse;
|
|
28
|
+
var internalServerErrorTextResponse = function (body) { return function () {
|
|
29
|
+
return (0, exports.toResponse)(500, 'InternalServerError', body);
|
|
30
|
+
}; };
|
|
31
|
+
exports.internalServerErrorTextResponse = internalServerErrorTextResponse;
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coorpacademy/app-review",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"description": "",
|
|
5
|
-
"type": "module",
|
|
6
5
|
"engines": {
|
|
7
6
|
"node": ">=16.15.0"
|
|
8
7
|
},
|
|
8
|
+
"license": "UNLICENSED",
|
|
9
9
|
"scripts": {
|
|
10
10
|
"start": "node commands/start.js",
|
|
11
11
|
"static": "node commands/build-static-webapp.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"clean:commonjs": "rm -rf lib",
|
|
18
18
|
"clean:es": "rm -rf es",
|
|
19
19
|
"clean": "concurrently \"npm run clean:commonjs\" \"npm run clean:es\"",
|
|
20
|
-
"test:unit": "
|
|
20
|
+
"test:unit": "ava"
|
|
21
21
|
},
|
|
22
22
|
"author": "CoorpAcademy",
|
|
23
23
|
"files": [
|
|
@@ -36,7 +36,9 @@
|
|
|
36
36
|
"./package.json": "./package.json"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@coorpacademy/components": "10.19.
|
|
39
|
+
"@coorpacademy/components": "10.19.9",
|
|
40
|
+
"cross-fetch": "^3.1.5",
|
|
41
|
+
"jwt-decode": "^3.1.2",
|
|
40
42
|
"react-redux": "^8.0.1",
|
|
41
43
|
"redux": "^4.2.0"
|
|
42
44
|
},
|
|
@@ -45,17 +47,20 @@
|
|
|
45
47
|
"react-native": "0.68.1"
|
|
46
48
|
},
|
|
47
49
|
"devDependencies": {
|
|
48
|
-
"
|
|
49
|
-
"chalk": "^
|
|
50
|
+
"ava": "^4.2.0",
|
|
51
|
+
"chalk": "^4.1.2",
|
|
50
52
|
"concurrently": "^5.2.0",
|
|
51
53
|
"connect-history-api-fallback": "^1.6.0",
|
|
54
|
+
"dotenv": "^16.0.1",
|
|
52
55
|
"esbuild": "^0.14.39",
|
|
53
|
-
"esbuild-css-modules-plugin": "
|
|
56
|
+
"esbuild-css-modules-plugin": "https://github.com/chrisdugne/esbuild-css-modules-plugin#main",
|
|
54
57
|
"esbuild-plugin-svgr": "^1.0.1",
|
|
55
58
|
"live-server": "^1.2.2",
|
|
59
|
+
"postcss-modules-values-replace": "^3.4.0",
|
|
56
60
|
"react-dom": "^17.0.2",
|
|
57
61
|
"redux-devtools-extension": "^2.13.9",
|
|
62
|
+
"ts-node": "^10.8.0",
|
|
58
63
|
"typescript": "^4.6.4"
|
|
59
64
|
},
|
|
60
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "f9a39c716e55d255c25c712981e895e6c8a30e7e"
|
|
61
66
|
}
|
package/readme.md
CHANGED
|
@@ -1,18 +1,48 @@
|
|
|
1
1
|
# App Review
|
|
2
2
|
|
|
3
|
+
📚 [Static Demo](http://coorpacademy.github.io/components/app-review)
|
|
4
|
+
|
|
3
5
|
## start local sandbox
|
|
4
6
|
|
|
5
7
|
```sh
|
|
6
8
|
npm start
|
|
7
9
|
```
|
|
8
10
|
|
|
11
|
+
requirements:
|
|
12
|
+
|
|
13
|
+
- [mooc](https://github.com/CoorpAcademy/coorpacademy) installed and running to expose a local API.
|
|
14
|
+
- duplicated `.env.sample` to `.env` with a local token to access the mooc API.
|
|
15
|
+
|
|
16
|
+
## developing views locally
|
|
17
|
+
|
|
18
|
+
Be sure to build `es/` on `@coorpademy/components`
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
> cd ../@coorpademy-components
|
|
22
|
+
> npm run build:es
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
then start [the sandbox](#start-local-sandbox)
|
|
26
|
+
|
|
9
27
|
## generate /static
|
|
10
28
|
|
|
11
29
|
```sh
|
|
12
30
|
npm run static
|
|
13
31
|
```
|
|
14
32
|
|
|
15
|
-
(This script is
|
|
33
|
+
(This script is used by lerna to publish the [static web app](http://coorpacademy.github.io/components/app-review))
|
|
34
|
+
|
|
35
|
+
## unit tests
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
npm run test:unit
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
or
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npx ava --watch
|
|
45
|
+
```
|
|
16
46
|
|
|
17
47
|
## dependencies notes
|
|
18
48
|
|
|
@@ -25,3 +55,10 @@ npm run static
|
|
|
25
55
|
### tmp notes
|
|
26
56
|
|
|
27
57
|
export: <https://stackoverflow.com/a/70020984/959219>
|
|
58
|
+
|
|
59
|
+
css modules:
|
|
60
|
+
|
|
61
|
+
- <https://github.com/evanw/esbuild/issues/20>
|
|
62
|
+
- <https://github.com/indooorsman/esbuild-css-modules-plugin/issues/35>
|
|
63
|
+
- <https://github.com/princed/postcss-modules-values-replace>
|
|
64
|
+
- <https://github.com/CoorpAcademy/coorpacademy-lambda/blob/master/teams/postcss.config.js#L4>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const RECEIVED_COURSE = '@@api/RECEIVED_COURSE';
|
|
2
|
+
|
|
3
|
+
export type ReceivedCourse = {
|
|
4
|
+
type: '@@api/RECEIVED_COURSE';
|
|
5
|
+
payload: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const receivedCourse = (course: any): ReceivedCourse => ({
|
|
9
|
+
type: RECEIVED_COURSE,
|
|
10
|
+
payload: course
|
|
11
|
+
});
|
package/src/actions/index.ts
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
+
import {ReceivedCourse} from './courses';
|
|
2
|
+
import {NavigateBack, NavigateTo, StartApp} from './navigation';
|
|
3
|
+
import {StoreToken} from './token';
|
|
4
|
+
|
|
5
|
+
export * from './courses';
|
|
1
6
|
export * from './navigation';
|
|
7
|
+
export * from './token';
|
|
8
|
+
|
|
9
|
+
export type Action = StartApp | StoreToken | NavigateBack | NavigateTo | ReceivedCourse;
|
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
import {ActionCreator} from 'redux';
|
|
2
|
+
import {AppOptions} from '..';
|
|
2
3
|
|
|
3
4
|
export const NAVIGATE_TO = '@@navigation/NAVIGATE_TO';
|
|
4
5
|
export const NAVIGATE_BACK = '@@navigation/NAVIGATE_BACK';
|
|
6
|
+
export const START_APP = '@@navigation/START_APP';
|
|
5
7
|
|
|
6
|
-
export type
|
|
8
|
+
export type NavigateTo = {
|
|
7
9
|
type: '@@navigation/NAVIGATE_TO';
|
|
8
10
|
payload: string;
|
|
9
11
|
};
|
|
10
12
|
|
|
11
|
-
export type
|
|
13
|
+
export type NavigateBack = {
|
|
12
14
|
type: '@@navigation/NAVIGATE_BACK';
|
|
13
15
|
};
|
|
14
16
|
|
|
15
|
-
export
|
|
17
|
+
export type StartApp = {
|
|
18
|
+
type: '@@navigation/START_APP';
|
|
19
|
+
payload: AppOptions;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const navigateTo: ActionCreator<NavigateTo> = (newPath: string) => ({
|
|
16
23
|
type: NAVIGATE_TO,
|
|
17
24
|
payload: newPath
|
|
18
25
|
});
|
|
19
26
|
|
|
20
|
-
export const navigateBack: ActionCreator
|
|
27
|
+
export const navigateBack: ActionCreator<NavigateBack> = () => ({
|
|
21
28
|
type: NAVIGATE_BACK
|
|
22
29
|
});
|
|
30
|
+
|
|
31
|
+
export const startApp = (options: AppOptions): StartApp => ({
|
|
32
|
+
type: START_APP,
|
|
33
|
+
payload: options
|
|
34
|
+
});
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import {storiesOf} from '@storybook/react-native';
|
|
3
|
-
import RevisionHome from './revision-home';
|
|
1
|
+
// import * as React from 'react';
|
|
2
|
+
// import {storiesOf} from '@storybook/react-native';
|
|
3
|
+
// import RevisionHome from './revision-home';
|
|
4
4
|
|
|
5
|
-
const emptySkills: [] = [];
|
|
6
|
-
const skillsToRevise: {title: string; info: string}[] = [
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
];
|
|
5
|
+
// const emptySkills: [] = [];
|
|
6
|
+
// const skillsToRevise: {title: string; info: string}[] = [
|
|
7
|
+
// {title: 'Negotiation and powers of persuasion', info: '75 questions to revise'},
|
|
8
|
+
// {title: 'Negotiation and powers of persuasion', info: '75 questions to revise'},
|
|
9
|
+
// {title: 'Negotiation and powers of persuasion', info: '75 questions to revise'},
|
|
10
|
+
// {title: 'Negotiation and powers of persuasion', info: '75 questions to revise'},
|
|
11
|
+
// {title: 'Creativity and innovation', info: '75 questions to revise'}
|
|
12
|
+
// ];
|
|
13
13
|
|
|
14
|
-
storiesOf('RevisionHome', module)
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
// storiesOf('RevisionHome', module)
|
|
15
|
+
// .add('No skills', () => <RevisionHome skillsToRevise={emptySkills} />)
|
|
16
|
+
// .add('Few skills', () => <RevisionHome skillsToRevise={skillsToRevise} />);
|
package/src/configure-store.ts
CHANGED
|
@@ -4,9 +4,15 @@ import {composeWithDevTools} from 'redux-devtools-extension';
|
|
|
4
4
|
|
|
5
5
|
import rootReducer from './reducers';
|
|
6
6
|
|
|
7
|
+
import {State as NavigationState} from './reducers/navigation';
|
|
8
|
+
import {State as TokenState} from './reducers/token';
|
|
9
|
+
import onStartApp from './middlewares/on-start-app';
|
|
10
|
+
|
|
7
11
|
const preloadedState = undefined;
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
// -----------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
export default function configureStore() {
|
|
10
16
|
const _compose =
|
|
11
17
|
process.env.NODE_ENV !== 'production'
|
|
12
18
|
? composeWithDevTools({
|
|
@@ -16,8 +22,15 @@ export default function configureStore(services) {
|
|
|
16
22
|
})
|
|
17
23
|
: compose;
|
|
18
24
|
|
|
19
|
-
const enhancer = _compose(applyMiddleware(thunk));
|
|
25
|
+
const enhancer = _compose(applyMiddleware(thunk, onStartApp));
|
|
20
26
|
const store = createStore(rootReducer, preloadedState, enhancer);
|
|
21
27
|
|
|
22
28
|
return store;
|
|
23
29
|
}
|
|
30
|
+
|
|
31
|
+
// -----------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
export type StoreState = {
|
|
34
|
+
navigation: NavigationState;
|
|
35
|
+
token: TokenState;
|
|
36
|
+
};
|
package/src/index.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import {connect, Provider} from 'react-redux';
|
|
|
3
3
|
import AppReviewRootView from '@coorpacademy/components/es/template/app-review/root-view/root-view';
|
|
4
4
|
|
|
5
5
|
import configureStore from './configure-store';
|
|
6
|
-
import {navigateTo, navigateBack} from './actions/navigation';
|
|
6
|
+
import {navigateTo, navigateBack, startApp} from './actions/navigation';
|
|
7
7
|
import {getCurrentViewName} from './reducers/navigation';
|
|
8
8
|
|
|
9
9
|
// -----------------------------------------------------------------------------
|
|
@@ -17,11 +17,12 @@ const App = connect(mapStateToProps, mapDispatchToProps)(AppReviewRootView);
|
|
|
17
17
|
|
|
18
18
|
// -----------------------------------------------------------------------------
|
|
19
19
|
|
|
20
|
-
const AppRevision = ({
|
|
20
|
+
const AppRevision = ({options}: Props) => {
|
|
21
21
|
const [store, setStore] = useState(null);
|
|
22
22
|
|
|
23
23
|
useEffect(() => {
|
|
24
|
-
const store = configureStore(
|
|
24
|
+
const store = configureStore();
|
|
25
|
+
store.dispatch(startApp(options));
|
|
25
26
|
setStore(store);
|
|
26
27
|
}, []);
|
|
27
28
|
|
|
@@ -36,4 +37,12 @@ const AppRevision = ({services}) => {
|
|
|
36
37
|
|
|
37
38
|
// -----------------------------------------------------------------------------
|
|
38
39
|
|
|
40
|
+
type Props = {options: AppOptions};
|
|
41
|
+
|
|
42
|
+
export type AppOptions = {
|
|
43
|
+
token: string;
|
|
44
|
+
theme?: any;
|
|
45
|
+
translations?: any;
|
|
46
|
+
};
|
|
47
|
+
|
|
39
48
|
export default AppRevision;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import fetch from 'cross-fetch';
|
|
2
|
+
import type {Middleware} from 'redux';
|
|
3
|
+
import {Dispatch} from 'redux';
|
|
4
|
+
|
|
5
|
+
import {Action, receivedCourse, START_APP, storeToken} from '../actions';
|
|
6
|
+
import {StoreState} from '../configure-store';
|
|
7
|
+
import fetchCourse from '../services/fetch-demo';
|
|
8
|
+
|
|
9
|
+
const onStartApp: Middleware<{}, StoreState, Dispatch<Action>> = ({dispatch}) => next => (
|
|
10
|
+
action: Action
|
|
11
|
+
) => {
|
|
12
|
+
if (action.type === START_APP) {
|
|
13
|
+
const {token} = action.payload;
|
|
14
|
+
dispatch(storeToken(token));
|
|
15
|
+
|
|
16
|
+
// --------------
|
|
17
|
+
// demo service
|
|
18
|
+
|
|
19
|
+
const language = 'fr';
|
|
20
|
+
const universalRef = 'dis_xxx15';
|
|
21
|
+
|
|
22
|
+
fetchCourse(token, language, universalRef).then(course => {
|
|
23
|
+
dispatch(receivedCourse(course));
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return next(action);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default onStartApp;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {ReceivedCourse, RECEIVED_COURSE} from '../actions';
|
|
2
|
+
|
|
3
|
+
// -----------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export type State = Array<any>;
|
|
6
|
+
export const initialState: State = [];
|
|
7
|
+
|
|
8
|
+
// -----------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
const reducer = (state: State = initialState, action: ReceivedCourse): State => {
|
|
11
|
+
switch (action.type) {
|
|
12
|
+
case RECEIVED_COURSE: {
|
|
13
|
+
return [...state, action.payload];
|
|
14
|
+
}
|
|
15
|
+
default:
|
|
16
|
+
return state;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// -----------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
export default reducer;
|
package/src/reducers/index.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import {combineReducers} from 'redux';
|
|
2
|
+
|
|
3
|
+
import courses from './courses';
|
|
2
4
|
import navigation from './navigation';
|
|
5
|
+
import token from './token';
|
|
3
6
|
|
|
4
7
|
const rootReducer = combineReducers({
|
|
5
|
-
|
|
8
|
+
courses,
|
|
9
|
+
navigation,
|
|
10
|
+
token
|
|
6
11
|
});
|
|
7
12
|
|
|
8
13
|
export default rootReducer;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import {NAVIGATE_BACK, NAVIGATE_TO} from '../actions/navigation';
|
|
2
|
-
import type {
|
|
2
|
+
import type {NavigateTo, NavigateBack} from '../actions/navigation';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// -----------------------------------------------------------------------------
|
|
5
5
|
|
|
6
|
+
export type State = Array<string>;
|
|
6
7
|
export const initialState: State = ['home'];
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
// -----------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
const reducer = (state: State = initialState, action: NavigateTo | NavigateBack): State => {
|
|
9
12
|
switch (action.type) {
|
|
10
13
|
case NAVIGATE_TO: {
|
|
11
14
|
return [...state, action.payload];
|
|
@@ -20,5 +23,10 @@ const reducer = (state: State = initialState, action: $NAVIGATE_TO | $NAVIGATE_B
|
|
|
20
23
|
}
|
|
21
24
|
};
|
|
22
25
|
|
|
26
|
+
// -----------------------------------------------------------------------------
|
|
27
|
+
|
|
23
28
|
export const getCurrentViewName = appState => appState.navigation[appState.navigation.length - 1];
|
|
29
|
+
|
|
30
|
+
// -----------------------------------------------------------------------------
|
|
31
|
+
|
|
24
32
|
export default reducer;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {StoreToken, STORE_TOKEN} from '../actions';
|
|
2
|
+
|
|
3
|
+
// -----------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export type State = string;
|
|
6
|
+
export const initialState: State = null;
|
|
7
|
+
|
|
8
|
+
// -----------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
const reducer = (state: State = initialState, action: StoreToken): State => {
|
|
11
|
+
switch (action.type) {
|
|
12
|
+
case STORE_TOKEN: {
|
|
13
|
+
return action.payload;
|
|
14
|
+
}
|
|
15
|
+
default:
|
|
16
|
+
return state;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// -----------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
export const getToken = appState => appState.token;
|
|
23
|
+
|
|
24
|
+
// -----------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
export default reducer;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import {fetchCourse as _fetchCourse} from './fetch-demo';
|
|
3
|
+
import {okJSONResponse} from './fetch.mocks';
|
|
4
|
+
import type {CatalogHits} from './fetch-demo';
|
|
5
|
+
|
|
6
|
+
test('should fetch a demo course', async t => {
|
|
7
|
+
const token =
|
|
8
|
+
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
|
|
9
|
+
const language = 'fr';
|
|
10
|
+
const universalRef = 'bar';
|
|
11
|
+
|
|
12
|
+
const result: CatalogHits = {hits: [{title: 'Digital IQ test'}]};
|
|
13
|
+
const fetchCourse = _fetchCourse(okJSONResponse(result));
|
|
14
|
+
const course = await fetchCourse(token, language, universalRef);
|
|
15
|
+
t.is(course.title, 'Digital IQ test');
|
|
16
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import crossFetch from 'cross-fetch';
|
|
2
|
+
import decode from 'jwt-decode';
|
|
3
|
+
import {Fetch, toJSON} from './fetch-responses';
|
|
4
|
+
|
|
5
|
+
// -----------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
type JWT = {
|
|
8
|
+
exp: number;
|
|
9
|
+
iat: number;
|
|
10
|
+
grants: unknown;
|
|
11
|
+
iss: string;
|
|
12
|
+
user: string;
|
|
13
|
+
usage: string;
|
|
14
|
+
host: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type QueryParams = {
|
|
18
|
+
[key: string]: string | number | boolean;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const buildUrlQueryParams = (params: QueryParams) =>
|
|
22
|
+
Object.keys(params)
|
|
23
|
+
.map(key => {
|
|
24
|
+
const value = params[key].toString();
|
|
25
|
+
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
26
|
+
})
|
|
27
|
+
.join('&');
|
|
28
|
+
|
|
29
|
+
// -----------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
const fetchCourse = (fetch: Fetch) => async (token, language, universalRef): Promise<Course> => {
|
|
32
|
+
const jwt: JWT = decode(token);
|
|
33
|
+
const query = {
|
|
34
|
+
type: 'course',
|
|
35
|
+
universalRef,
|
|
36
|
+
lang: language
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const response = await fetch(`${jwt.host}/api/v2/contents?${buildUrlQueryParams(query)}`, {
|
|
40
|
+
headers: {authorization: token}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const {hits} = (await toJSON(response)) as CatalogHits;
|
|
44
|
+
return hits?.[0];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// -----------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
export type Course = {title};
|
|
50
|
+
export type CatalogHits = {hits: Course[]};
|
|
51
|
+
|
|
52
|
+
// -----------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
export {fetchCourse};
|
|
55
|
+
export default fetchCourse(crossFetch);
|