diff --git a/package-lock.json b/package-lock.json
index 8973700..38bc4c3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,7 +29,6 @@
"import-jsx": "^5.0.0",
"ink-testing-library": "^3.0.0",
"nodemon": "^3.1.10",
- "npm-run-all": "^4.1.5",
"prettier": "^2.8.7",
"xo": "^0.53.1"
},
@@ -5648,13 +5647,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/json-parse-better-errors": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
- "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
@@ -6056,15 +6048,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/memorystream": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
- "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
- "dev": true,
- "engines": {
- "node": ">= 0.10.0"
- }
- },
"node_modules/meow": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/meow/-/meow-11.0.0.tgz",
@@ -6257,13 +6240,6 @@
"license": "MIT",
"peer": true
},
- "node_modules/nice-try": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
- "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
@@ -6428,292 +6404,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/npm-run-all": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
- "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "chalk": "^2.4.1",
- "cross-spawn": "^6.0.5",
- "memorystream": "^0.3.1",
- "minimatch": "^3.0.4",
- "pidtree": "^0.3.0",
- "read-pkg": "^3.0.0",
- "shell-quote": "^1.6.1",
- "string.prototype.padend": "^3.0.0"
- },
- "bin": {
- "npm-run-all": "bin/npm-run-all/index.js",
- "run-p": "bin/run-p/index.js",
- "run-s": "bin/run-s/index.js"
- },
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/npm-run-all/node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-all/node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-all/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/npm-run-all/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/npm-run-all/node_modules/cross-spawn": {
- "version": "6.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
- "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "nice-try": "^1.0.4",
- "path-key": "^2.0.1",
- "semver": "^5.5.0",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- },
- "engines": {
- "node": ">=4.8"
- }
- },
- "node_modules/npm-run-all/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/npm-run-all/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-all/node_modules/hosted-git-info": {
- "version": "2.8.9",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
- "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/npm-run-all/node_modules/load-json-file": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
- "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "parse-json": "^4.0.0",
- "pify": "^3.0.0",
- "strip-bom": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-all/node_modules/normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- }
- },
- "node_modules/npm-run-all/node_modules/parse-json": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "error-ex": "^1.3.1",
- "json-parse-better-errors": "^1.0.1"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-all/node_modules/path-key": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-all/node_modules/path-type": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
- "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "pify": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-all/node_modules/pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-all/node_modules/read-pkg": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
- "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "load-json-file": "^4.0.0",
- "normalize-package-data": "^2.3.2",
- "path-type": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-all/node_modules/resolve": {
- "version": "1.22.10",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
- "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-core-module": "^2.16.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/npm-run-all/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/npm-run-all/node_modules/shebang-command": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
- "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "shebang-regex": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/npm-run-all/node_modules/shebang-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
- "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/npm-run-all/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-all/node_modules/which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "which": "bin/which"
- }
- },
"node_modules/npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@@ -7203,19 +6893,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/pidtree": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz",
- "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "pidtree": "bin/pidtree.js"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
"node_modules/pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
@@ -8357,19 +8034,6 @@
"node": ">=8"
}
},
- "node_modules/shell-quote": {
- "version": "1.8.3",
- "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
- "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
@@ -8646,25 +8310,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/string.prototype.padend": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz",
- "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.2",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/string.prototype.repeat": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
diff --git a/source/app.js b/source/app.js
index 96476c8..c23378b 100644
--- a/source/app.js
+++ b/source/app.js
@@ -3,192 +3,385 @@ import { Text, Box } from 'ink';
import fetch from 'node-fetch';
const locations = {
- Nancy: { latitude: 48.6921, longitude: 6.1844 },
- Paris: { latitude: 48.8566, longitude: 2.3522 }
+ Nancy: { latitude: 48.6921, longitude: 6.1844 },
+ Paris: { latitude: 48.8566, longitude: 2.3522 }
+};
+
+const INTER_ID = 6684; // SC Internacional team id
+const PARIS_ID = 1045; // Paris FC team id
+
+const TASKTROVE_API = 'https://tasktrove.couraud.xyz/api/v1/tasks';
+const TASKTROVE_TOKEN = 'eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJuYW1lIjoidGFza3Ryb3ZlIiwiaXNzIjoibWVtb3MiLCJzdWIiOiIzIiwiYXVkIjpbInVzZXIuYWNjZXNzLXRva2VuIl0sImlhdCI6MTc1OTk5MjI0N30.666jJ97j9a3d8c3a2a2a2a2a2a2a2a2a2a2a2a2a2a2'; // From your memo API
+
+const weatherCodeMap = {
+ 0: { desc: 'Ciel clair', color: 'yellow' },
+ 1: { desc: 'Principalement clair', color: 'yellow' },
+ 2: { desc: 'Partiellement nuageux', color: 'cyan' },
+ 3: { desc: 'Couvert', color: 'gray' },
+ 45: { desc: 'Brouillard', color: 'gray' },
+ 48: { desc: 'Brouillard givrant', color: 'gray' },
+ 51: { desc: 'Bruine légère', color: 'blue' },
+ 53: { desc: 'Bruine modérée', color: 'blue' },
+ 55: { desc: 'Bruine dense', color: 'blue' },
+ 56: { desc: 'Bruine verglaçante légère', color: 'blue' },
+ 57: { desc: 'Bruine verglaçante dense', color: 'blue' },
+ 61: { desc: 'Pluie faible', color: 'blue' },
+ 63: { desc: 'Pluie modérée', color: 'blue' },
+ 65: { desc: 'Pluie forte', color: 'blue' },
+ 66: { desc: 'Pluie verglaçante légère', color: 'blue' },
+ 67: { desc: 'Pluie verglaçante forte', color: 'blue' },
+ 71: { desc: 'Chute de neige légère', color: 'white' },
+ 73: { desc: 'Chute de neige modérée', color: 'white' },
+ 75: { desc: 'Chute de neige forte', color: 'white' },
+ 77: { desc: 'Grains de neige', color: 'white' },
+ 80: { desc: 'Averses de pluie faibles', color: 'blue' },
+ 81: { desc: 'Averses de pluie modérées', color: 'blue' },
+ 82: { desc: 'Averses de pluie violentes', color: 'blue' },
+ 85: { desc: 'Averses de neige faibles', color: 'white' },
+ 86: { desc: 'Averses de neige fortes', color: 'white' },
+ 95: { desc: 'Orage', color: 'magenta' },
+ 96: { desc: 'Orage avec faible grêle', color: 'magenta' },
+ 99: { desc: 'Orage avec forte grêle', color: 'magenta' }
};
function formatTime(date) {
- return date.toLocaleTimeString('fr-FR', { hour12: false });
+ return date.toLocaleTimeString('fr-FR', { hour12: false });
}
function formatDate(date) {
- return date.toLocaleDateString('fr-FR', {
- weekday: 'long',
- year: 'numeric',
- month: 'long',
- day: 'numeric'
- });
+ return date.toLocaleDateString('fr-FR', {
+ weekday: 'long',
+ year: 'numeric',
+ month: 'long',
+ day: 'numeric'
+ });
}
function formatDateTimeUTC(utcString) {
- const date = new Date(utcString);
- return {
- date: formatDate(date),
- time: formatTime(date)
- };
+ const date = new Date(utcString);
+ return {
+ date: formatDate(date),
+ time: formatTime(date)
+ };
}
async function fetchWeather(lat, lon) {
- const url = `https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}¤t_weather=true&temperature_unit=celsius&timezone=Europe/Paris`;
- const response = await fetch(url);
- const data = await response.json();
- return data.current_weather;
+ const url = `https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}¤t_weather=true&temperature_unit=celsius&timezone=Europe/Paris`;
+ const response = await fetch(url);
+ const data = await response.json();
+ return data.current_weather;
}
-const weatherCodeMap = {
- 0: { desc: 'Ciel clair', color: 'yellow' },
- 1: { desc: 'Principalement clair', color: 'yellow' },
- 2: { desc: 'Partiellement nuageux', color: 'cyan' },
- 3: { desc: 'Couvert', color: 'gray' },
- 45: { desc: 'Brouillard', color: 'gray' },
- 48: { desc: 'Brouillard givrant', color: 'gray' },
- 51: { desc: 'Bruine légère', color: 'blue' },
- 53: { desc: 'Bruine modérée', color: 'blue' },
- 55: { desc: 'Bruine dense', color: 'blue' },
- 56: { desc: 'Bruine verglaçante légère', color: 'blue' },
- 57: { desc: 'Bruine verglaçante dense', color: 'blue' },
- 61: { desc: 'Pluie faible', color: 'blue' },
- 63: { desc: 'Pluie modérée', color: 'blue' },
- 65: { desc: 'Pluie forte', color: 'blue' },
- 66: { desc: 'Pluie verglaçante légère', color: 'blue' },
- 67: { desc: 'Pluie verglaçante forte', color: 'blue' },
- 71: { desc: 'Chute de neige légère', color: 'white' },
- 73: { desc: 'Chute de neige modérée', color: 'white' },
- 75: { desc: 'Chute de neige forte', color: 'white' },
- 77: { desc: 'Grains de neige', color: 'white' },
- 80: { desc: 'Averses de pluie faibles', color: 'blue' },
- 81: { desc: 'Averses de pluie modérées', color: 'blue' },
- 82: { desc: 'Averses de pluie violentes', color: 'blue' },
- 85: { desc: 'Averses de neige faibles', color: 'white' },
- 86: { desc: 'Averses de neige fortes', color: 'white' },
- 95: { desc: 'Orage', color: 'magenta' },
- 96: { desc: 'Orage avec faible grêle', color: 'magenta' },
- 99: { desc: 'Orage avec forte grêle', color: 'magenta' }
+async function fetchScheduledMatches(teamId) {
+ const url = `https://api.football-data.org/v4/teams/${teamId}/matches?status=SCHEDULED`;
+ try {
+ const response = await fetch(url, {
+ headers: { "X-Auth-Token": "1535f68086e542528841b5e276f50b45" }
+ });
+ const data = await response.json();
+ if (!data.matches) return [];
+ return data.matches.map(match => {
+ let opponent, homeAway;
+ if (match.homeTeam.id === teamId) {
+ opponent = match.awayTeam.name;
+ homeAway = 'Home';
+ } else if (match.awayTeam.id === teamId) {
+ opponent = match.homeTeam.name;
+ homeAway = 'Away';
+ } else {
+ return null;
+ }
+ const { date, time } = formatDateTimeUTC(match.utcDate);
+ return { date, time, opponent, homeAway };
+ }).filter(Boolean);
+ } catch {
+ return [];
+ }
+}
+function translateHomeAway(homeAway) {
+ if (homeAway === 'Home') return 'domicile';
+ if (homeAway === 'Away') return 'extérieur';
+ return homeAway;
+}
+
+function renderWeather(location, weather) {
+ if (!weather) return {location}: Loading weather...;
+
+ const weatherInfo = weatherCodeMap[weather.weathercode] || { desc: 'Unknown', color: 'white' };
+
+ return (
+
+ {location}: {weatherInfo.desc},{' '}
+ {weather.temperature}°C (Vent : {weather.windspeed} km/h)
+
+ );
+}
+
+async function fetchDeviceInfo() {
+ const url = 'http://192.168.0.19:19837/device-info';
+ const response = await fetch(url);
+ if (!response.ok) throw new Error('Erreur HTTP ' + response.status);
+ return response.json();
+}
+
+const LoadingBar = ({ percentage }) => {
+ const width = 30;
+ const filledWidth = Math.round((percentage / 100) * width);
+ const emptyWidth = width - filledWidth;
+
+ return (
+
+ [
+ {'='.repeat(filledWidth)}
+ {' '.repeat(emptyWidth)}
+ ]
+ {percentage}%
+
+ );
};
-export default function App({ name = 'Mathias' }) {
- const [now, setNow] = useState(new Date());
- const [weatherNancy, setWeatherNancy] = useState(null);
- const [weatherParis, setWeatherParis] = useState(null);
-
- const [matchesInter, setMatchesInter] = useState(null);
- const [matchesParis, setMatchesParis] = useState(null);
-
- const INTER_ID = 6684; // SC Internacional team id
- const PARIS_ID = 1045; // Paris FC team id
-
- useEffect(() => {
- const timer = setInterval(() => {
- setNow(new Date());
- }, 1000);
-
- async function updateWeather() {
- try {
- const nancyData = await fetchWeather(locations.Nancy.latitude, locations.Nancy.longitude);
- const parisData = await fetchWeather(locations.Paris.latitude, locations.Paris.longitude);
- setWeatherNancy(nancyData);
- setWeatherParis(parisData);
- } catch (error) {
- // gestion d'erreur météo
- }
- }
-
- async function fetchMatches(teamId, setMatches) {
- try {
- const response = await fetch(
- `https://api.football-data.org/v4/teams/${teamId}/matches?status=SCHEDULED`,
- {
- headers: { "X-Auth-Token": "1535f68086e542528841b5e276f50b45" } // Remplace par ton token
- }
- );
- const data = await response.json();
-
- const filtered = data.matches.map(match => {
- let opponent, homeAway;
- if (match.homeTeam.id === teamId) {
- opponent = match.awayTeam.name;
- homeAway = 'Home';
- } else if (match.awayTeam.id === teamId) {
- opponent = match.homeTeam.name;
- homeAway = 'Away';
- } else {
- return null;
- }
- const { date, time } = formatDateTimeUTC(match.utcDate);
- return { date, time, opponent, homeAway };
- }).filter(Boolean);
-
- setMatches(filtered);
- } catch (error) {
- setMatches([]);
- }
- }
-
- updateWeather();
- fetchMatches(INTER_ID, setMatchesInter);
- fetchMatches(PARIS_ID, setMatchesParis);
-
- const weatherInterval = setInterval(updateWeather, 60000);
-
- return () => {
- clearInterval(timer);
- clearInterval(weatherInterval);
- };
- }, []);
-
- const renderWeather = (location, weather) => {
- if (!weather) return {location}: Loading weather...;
-
- const weatherInfo = weatherCodeMap[weather.weathercode] || { desc: 'Unknown', color: 'white' };
-
- return (
-
- {location}: {weatherInfo.desc},{' '}
- {weather.temperature}°C (Vent : {weather.windspeed} km/h)
-
- );
- };
-
- const translateHomeAway = (homeAway) => {
- if (homeAway === 'Home') return 'domicile';
- if (homeAway === 'Away') return 'extérieur';
- return homeAway;
- };
+function renderDeviceInfo(deviceInfo, deviceError) {
+ if (deviceError) {
+ return {deviceError};
+ }
+ if (!deviceInfo) {
+ return Chargement des informations...;
+ }
+ const percentage = deviceInfo.percentage;
+ if (percentage == null) {
+ return Status : {deviceInfo.status || 'N/A'};
+ } else {
return (
-
-
- Hello, {name} !
-
- {formatDate(now)}
- {formatTime(now)}
- {renderWeather('Nancy', weatherNancy)}
- {renderWeather('Paris', weatherParis)}
-
-
- Matches à venir de SC Internacional :
- {!matchesInter && Chargement des matchs...}
- {matchesInter && matchesInter.length === 0 && Aucun match trouvé.}
- {matchesInter && matchesInter.slice(0, 2).map((m, i) => (
-
- {m.date} {m.time} - SC Internacional vs {m.opponent} ({translateHomeAway(m.homeAway)})
-
- ))}
-
-
-
- Matches à venir de Paris FC :
- {!matchesParis && Chargement des matchs...}
- {matchesParis && matchesParis.length === 0 && Aucun match trouvé.}
- {matchesParis && matchesParis.slice(0, 2).map((m, i) => (
-
- {m.date} {m.time} - Paris FC vs {m.opponent} ({translateHomeAway(m.homeAway)})
-
- ))}
-
-
- Press Ctrl+C to exit.
-
+
+
+ Temps restant : {deviceInfo.remainingTime || 'N/A'}
+ Status : {deviceInfo.status || 'N/A'}
+
);
+ }
+}
+
+function formatMemoContent(markdownContent) {
+ if (!markdownContent) return "";
+ return markdownContent.split('\n').map(line => {
+ const taskItemMatch = line.match(/^-\s*\[( |x|X)\]\s*/);
+ if (taskItemMatch) {
+ return '- ' + line.slice(taskItemMatch[0].length);
+ }
+ return line;
+ }).join('\n');
+}
+
+async function fetchLatestMemo() {
+ const url = "https://memos.couraud.xyz/api/v1/memos?page=1&perPage=1";
+ try {
+ const response = await fetch(url, {
+ headers: {
+ Authorization: "Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJuYW1lIjoiZ3JvY2VyaWVzIiwiaXNzIjoibWVtb3MiLCJzdWIiOiIyIiwiYXVkIjpbInVzZXIuYWNjZXNzLXRva2VuIl0sImlhdCI6MTc2MDI3NzQwMX0.H8m6LSaav7cuiQgt_rrzB7Fx4UM7Un11M2S0L5JJfPc"
+ }
+ });
+ if (!response.ok) {
+ throw new Error(`HTTP error ${response.status}`);
+ }
+ const json = await response.json();
+
+ const memosArray = json.memos;
+ if (memosArray && memosArray.length > 0) {
+ return formatMemoContent(memosArray[0].content);
+ }
+ return "Aucune note trouvée.";
+ } catch (error) {
+ return `Erreur lors de la récupération de la note: ${error.message}`;
+ }
+}
+
+// New function to fetch and render TaskTrove tasks
+async function fetchTaskTroveTasks() {
+ try {
+ const response = await fetch(TASKTROVE_API, {
+ headers: {
+ Authorization: `Bearer ${TASKTROVE_TOKEN}`
+ }
+ });
+
+ if (!response.ok) return [];
+
+ const data = await response.json();
+ const tasks = data.tasks || [];
+ const today = new Date().toISOString().split('T')[0];
+
+ return tasks
+ .filter(task => {
+ if (task.completed) return false;
+ const isDueToday = task.dueDate === today;
+ const isP1 = task.priority === 1;
+ const isP2 = task.priority === 2;
+ return isDueToday || isP1 || isP2;
+ })
+ .map(task => ({
+ title: task.title,
+ priority: task.priority,
+ dueDate: task.dueDate
+ }));
+
+ } catch (err) {
+ return [];
+ }
+}
+
+function renderTaskTroveList(tasks) {
+ if (!tasks) {
+ return Chargement des tâches...;
+ }
+
+ if (tasks.length === 0) {
+ return Aucune tâche à afficher.;
+ }
+
+ return (
+
+ {tasks.map((task, index) => {
+ const color = task.priority === 1 ? 'red' : task.priority === 2 ? 'yellow' : 'white';
+ return (
+
+ - {task.title}
+
+ );
+ })}
+
+ );
+}
+
+export default function App({ name = 'Mathias' }) {
+ const [now, setNow] = useState(new Date());
+ const [weatherNancy, setWeatherNancy] = useState(null);
+ const [weatherParis, setWeatherParis] = useState(null);
+ const [matchesInter, setMatchesInter] = useState(null);
+ const [matchesParis, setMatchesParis] = useState(null);
+ const [deviceInfo, setDeviceInfo] = useState(null);
+ const [deviceError, setDeviceError] = useState(null);
+ const [latestMemo, setLatestMemo] = useState("Chargement de la dernière note...");
+ const [taskTroveTasks, setTaskTroveTasks] = useState(null);
+
+ useEffect(() => {
+ const timer = setInterval(() => setNow(new Date()), 1000);
+ return () => clearInterval(timer);
+ }, []);
+
+ async function updateWeatherData() {
+ try {
+ const [nancy, paris] = await Promise.all([
+ fetchWeather(locations.Nancy.latitude, locations.Nancy.longitude),
+ fetchWeather(locations.Paris.latitude, locations.Paris.longitude)
+ ]);
+ setWeatherNancy(nancy);
+ setWeatherParis(paris);
+ } catch (err) {}
+ }
+
+ async function updateMatchesData() {
+ try {
+ const [interMatches, parisMatches] = await Promise.all([
+ fetchScheduledMatches(INTER_ID),
+ fetchScheduledMatches(PARIS_ID)
+ ]);
+ setMatchesInter(interMatches);
+ setMatchesParis(parisMatches);
+ } catch (err) {}
+ }
+
+ async function updateDeviceInfo() {
+ try {
+ const data = await fetchDeviceInfo();
+ setDeviceInfo(data);
+ setDeviceError(null);
+ } catch (err) {
+ setDeviceError("Impossible de récupérer les informations du device");
+ setDeviceInfo(null);
+ }
+ }
+
+ async function updateLatestMemo() {
+ const memo = await fetchLatestMemo();
+ setLatestMemo(memo);
+ }
+
+ async function updateTaskTroveTasks() {
+ const tasks = await fetchTaskTroveTasks();
+ setTaskTroveTasks(tasks);
+ }
+
+ useEffect(() => {
+ updateWeatherData();
+ updateMatchesData();
+ updateDeviceInfo();
+ updateLatestMemo();
+ updateTaskTroveTasks();
+
+ const weatherInterval = setInterval(updateWeatherData, 60000);
+ const deviceInterval = setInterval(updateDeviceInfo, 60000);
+ const memoInterval = setInterval(updateLatestMemo, 60000);
+ const taskTroveInterval = setInterval(updateTaskTroveTasks, 60000);
+
+ return () => {
+ clearInterval(weatherInterval);
+ clearInterval(deviceInterval);
+ clearInterval(memoInterval);
+ clearInterval(taskTroveInterval);
+ };
+ }, []);
+
+ return (
+
+ Hello, {name} !
+ {formatDate(now)}
+ {formatTime(now)}
+
+ {renderWeather('Nancy', weatherNancy)}
+ {renderWeather('Paris', weatherParis)}
+
+
+ Matches à venir de SC Internacional :
+ {!matchesInter && Chargement des matchs...}
+ {matchesInter && matchesInter.length === 0 && Aucun match trouvé.}
+ {matchesInter && matchesInter.slice(0, 2).map((m, i) => (
+
+ {m.date} {m.time} - SC Internacional vs {m.opponent} ({translateHomeAway(m.homeAway)})
+
+ ))}
+
+
+
+ Matches à venir de Paris FC :
+ {!matchesParis && Chargement des matchs...}
+ {matchesParis && matchesParis.length === 0 && Aucun match trouvé.}
+ {matchesParis && matchesParis.slice(0, 2).map((m, i) => (
+
+ {m.date} {m.time} - Paris FC vs {m.opponent} ({translateHomeAway(m.homeAway)})
+
+ ))}
+
+
+
+ Informations du device :
+ {renderDeviceInfo(deviceInfo, deviceError)}
+
+
+
+ Liste de courses
+ {latestMemo.split('\n').map((line, index) => (
+ {line}
+ ))}
+
+
+
+ To-Do List
+ {renderTaskTroveList(taskTroveTasks)}
+
+
+ Press Ctrl+C to exit.
+
+ );
}