7 Commits

Author SHA1 Message Date
Nikolai Petukhov
a3484f4525 backend init 2024-09-28 12:51:59 +03:00
Nikolai Petukhov
876ef28221 0.2.4 2024-09-28 10:37:42 +03:00
Nikolai Petukhov
e6231f86b4 account page is done 2024-09-28 10:34:06 +03:00
Nikolai Petukhov
9d13f571d9 0.2.3 2024-09-28 10:00:38 +03:00
Nikolai Petukhov
f654851e1a fix dependencies 2024-09-28 09:56:43 +03:00
Askar Akhmetkhanov
3fb107fd8b Commit 2024-09-28 00:12:00 +03:00
Nikolai Petukhov
2a881f3920 small fix 2024-09-21 17:25:03 +03:00
25 changed files with 1046 additions and 53 deletions

View File

@@ -23,5 +23,6 @@ module.exports = {
},
config: {
"enterfront.api": "/api",
// paste stand URL to config
},
};

457
package-lock.json generated
View File

@@ -1,25 +1,28 @@
{
"name": "enterfront",
"version": "0.2.2",
"version": "0.2.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "enterfront",
"version": "0.2.2",
"version": "0.2.4",
"dependencies": {
"@brojs/cli": "^1.0.0",
"@brojs/create": "^1.0.0",
"@ijl/cli": "^5.1.0",
"@types/react": "^18.3.5",
"@types/react-dom": "^18.3.0",
"emoji-mart": "^5.6.0",
"express": "^4.19.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-emoji-picker": "^1.0.13",
"react-icons": "^5.3.0",
"react-router-dom": "^6.26.1",
"styled-components": "^6.1.13",
"typescript": "^5.5.4"
"typescript": "^5.5.4",
"ws": "^8.18.0"
}
},
"node_modules/@ampproject/remapping": {
@@ -2686,9 +2689,10 @@
}
},
"node_modules/@ijl/cli/node_modules/@types/react": {
"version": "17.0.80",
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.80.tgz",
"integrity": "sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA==",
"version": "17.0.83",
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.83.tgz",
"integrity": "sha512-l0m4ArKJvmFtR4e8UmKrj1pB4tUgOhJITf+mADyF/p69Ts1YAR/E+G9XEM0mHXKVRa1dQNHseyyDNzeuAXfXQw==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
@@ -2714,6 +2718,7 @@
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
"integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
@@ -2727,6 +2732,7 @@
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
"integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
@@ -2769,6 +2775,7 @@
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
"integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
@@ -3132,6 +3139,7 @@
"version": "0.16.8",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
"license": "MIT",
"optional": true,
"peer": true
},
@@ -3458,6 +3466,15 @@
"ajv": "^8.8.2"
}
},
"node_modules/amdefine": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
"integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==",
"license": "BSD-3-Clause OR MIT",
"engines": {
"node": ">=0.4.2"
}
},
"node_modules/ansi-html-community": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz",
@@ -3559,6 +3576,12 @@
"node": ">=0.10.0"
}
},
"node_modules/asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"license": "MIT"
},
"node_modules/assign-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
@@ -3567,6 +3590,15 @@
"node": ">=0.10.0"
}
},
"node_modules/ast-types": {
"version": "0.9.6",
"resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz",
"integrity": "sha512-qEdtR2UH78yyHX/AUNfXmJTlM48XoFZKBdwi1nzkI1mJL21cmbu0cvjxjpkXJ5NENMq42H+hNs8VLJcqXLerBQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -3687,6 +3719,15 @@
"node": ">=0.10.0"
}
},
"node_modules/base62": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/base62/-/base62-1.2.8.tgz",
"integrity": "sha512-V6YHUbjLxN1ymqNLb1DPHoU1CpfdL7d2YTIp5W3U4hhoG4hhxNmsFDs66M9EXxBiSEke5Bt5dwdfMwwZF70iLA==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/base64id": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
@@ -4094,6 +4135,64 @@
"resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz",
"integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w=="
},
"node_modules/commoner": {
"version": "0.10.8",
"resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz",
"integrity": "sha512-3/qHkNMM6o/KGXHITA14y78PcfmXh4+AOCJpSoF73h4VY1JpdGv3CHMS5+JW6SwLhfJt4RhNmLAa7+RRX/62EQ==",
"license": "MIT",
"dependencies": {
"commander": "^2.5.0",
"detective": "^4.3.1",
"glob": "^5.0.15",
"graceful-fs": "^4.1.2",
"iconv-lite": "^0.4.5",
"mkdirp": "^0.5.0",
"private": "^0.1.6",
"q": "^1.1.2",
"recast": "^0.11.17"
},
"bin": {
"commonize": "bin/commonize"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commoner/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"license": "MIT"
},
"node_modules/commoner/node_modules/glob": {
"version": "5.0.15",
"resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
"integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"license": "ISC",
"dependencies": {
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "2 || 3",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
}
},
"node_modules/commoner/node_modules/mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"license": "MIT",
"dependencies": {
"minimist": "^1.2.6"
},
"bin": {
"mkdirp": "bin/cmd.js"
}
},
"node_modules/component-emitter": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
@@ -4224,6 +4323,13 @@
"webpack": "^5.1.0"
}
},
"node_modules/core-js": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA==",
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
"license": "MIT"
},
"node_modules/core-js-compat": {
"version": "3.38.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz",
@@ -4437,6 +4543,15 @@
"node": ">=0.10.0"
}
},
"node_modules/defined": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz",
"integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/del": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
@@ -4531,6 +4646,28 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/detective": {
"version": "4.7.1",
"resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz",
"integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==",
"license": "MIT",
"dependencies": {
"acorn": "^5.2.1",
"defined": "^1.0.0"
}
},
"node_modules/detective/node_modules/acorn": {
"version": "5.7.4",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
"integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -4567,6 +4704,24 @@
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.18.tgz",
"integrity": "sha512-1OfuVACu+zKlmjsNdcJuVQuVE61sZOLbNM4JAQ1Rvh6EOj0/EUKhMJjRH73InPlXSh8HIJk1cVZ8pyOV/FMdUQ=="
},
"node_modules/emoji-annotation-to-unicode": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/emoji-annotation-to-unicode/-/emoji-annotation-to-unicode-0.2.4.tgz",
"integrity": "sha512-0GAasay1KK/a+Vns0aK1EwRMdLTvvvHO5Jc0SFwfwVhOhroIyT1IqBT8igZFrn3aw0u2b1LRshNsofkiL3jCkA==",
"license": "MIT"
},
"node_modules/emoji-emoticon-to-unicode": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/emoji-emoticon-to-unicode/-/emoji-emoticon-to-unicode-0.2.2.tgz",
"integrity": "sha512-fZ/wYomR+zc1/Sp/uY85M06XaGr+P+mH/uzh4l3rPPnv3YXrF3W2Cm/IqWcXvMw8m65/vmVvigBVqvkUfPJi4A==",
"license": "MIT"
},
"node_modules/emoji-mart": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/emoji-mart/-/emoji-mart-5.6.0.tgz",
"integrity": "sha512-eJp3QRe79pjwa+duv+n7+5YsNhRcMl812EcFVwrnRvYKoNPoQb5qxU8DG6Bgwji0akHdp6D4Ln6tYLG58MFSow==",
"license": "MIT"
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -4624,6 +4779,27 @@
"node": ">= 0.6"
}
},
"node_modules/engine.io/node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/enhanced-resolve": {
"version": "5.17.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
@@ -4644,6 +4820,19 @@
"node": ">=6"
}
},
"node_modules/envify": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/envify/-/envify-3.4.1.tgz",
"integrity": "sha512-XLiBFsLtNF0MOZl+vWU59yPb3C2JtrQY2CNJn22KH75zPlHWY5ChcAQuf4knJeWT/lLkrx3sqvhP/J349bt4Bw==",
"license": "MIT",
"dependencies": {
"jstransform": "^11.0.3",
"through": "~2.3.4"
},
"bin": {
"envify": "bin/envify"
}
},
"node_modules/envinfo": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz",
@@ -4721,6 +4910,31 @@
"node": ">=8.0.0"
}
},
"node_modules/esprima": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
"integrity": "sha512-AWwVMNxwhN8+NIPQzAQZCm7RkLC4RbM3B1OobMuyp3i+w73X57KCKaVIxaRZb+DYCojq7rspo+fmuQfAboyhFg==",
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/esprima-fb": {
"version": "15001.1.0-dev-harmony-fb",
"resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1.0-dev-harmony-fb.tgz",
"integrity": "sha512-59dDGQo2b3M/JfKIws0/z8dcXH2mnVHkfSPRhCYS91JNGfGNwr7GsSF6qzWZuOGvw5Ii0w9TtylrX07MGmlOoQ==",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/esrecurse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
@@ -5065,6 +5279,19 @@
"reusify": "^1.0.4"
}
},
"node_modules/fbjs": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.6.1.tgz",
"integrity": "sha512-4KW7tT33ytfazK3Ekvesbsa4A5J79hUrdXONQGZ0wM6i3PFc70YknF9kj1eyx3mDupgJ7Z+ifFhcMJ+ps2eZIw==",
"license": "BSD-3-Clause",
"dependencies": {
"core-js": "^1.0.0",
"loose-envify": "^1.0.0",
"promise": "^7.0.3",
"ua-parser-js": "^0.7.9",
"whatwg-fetch": "^0.9.0"
}
},
"node_modules/filesize": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
@@ -6468,6 +6695,46 @@
"graceful-fs": "^4.1.6"
}
},
"node_modules/jstransform": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/jstransform/-/jstransform-11.0.3.tgz",
"integrity": "sha512-LGm87w0A8E92RrcXt94PnNHkFqHmgDy3mKHvNZOG7QepKCTCH/VB6S+IEN+bT4uLN3gVpOT0vvOOVd96osG71g==",
"license": "BSD-3-Clause",
"dependencies": {
"base62": "^1.1.0",
"commoner": "^0.10.1",
"esprima-fb": "^15001.1.0-dev-harmony-fb",
"object-assign": "^2.0.0",
"source-map": "^0.4.2"
},
"bin": {
"jstransform": "bin/jstransform"
},
"engines": {
"node": ">=0.8.8"
}
},
"node_modules/jstransform/node_modules/object-assign": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
"integrity": "sha512-CdsOUYIh5wIiozhJ3rLQgmUTgcyzFwZZrqhkKhODMoGtPKM+wt0h0CNIoauJWMsS9822EdzPsF/6mb4nLvPN5g==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/jstransform/node_modules/source-map": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"integrity": "sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A==",
"license": "BSD-3-Clause",
"dependencies": {
"amdefine": ">=0.0.4"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/keygrip": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
@@ -6537,6 +6804,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lodash.compact": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/lodash.compact/-/lodash.compact-3.0.1.tgz",
"integrity": "sha512-2ozeiPi+5eBXW1CLtzjk8XQFhQOEMwwfxblqeq6EGyTxZJ1bPATqilY0e6g2SLQpP4KuMeuioBhEnWz5Pr7ICQ==",
"license": "MIT"
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -7342,6 +7615,15 @@
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
},
"node_modules/private": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
"integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -7350,6 +7632,15 @@
"node": ">= 0.6.0"
}
},
"node_modules/promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
"license": "MIT",
"dependencies": {
"asap": "~2.0.3"
}
},
"node_modules/prompts": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz",
@@ -7398,6 +7689,17 @@
"node": ">=6"
}
},
"node_modules/q": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
"integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
"deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)",
"license": "MIT",
"engines": {
"node": ">=0.6.0",
"teleport": ">=0.2.0"
}
},
"node_modules/qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
@@ -7717,6 +8019,60 @@
"react": "^18.3.1"
}
},
"node_modules/react-emoji": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/react-emoji/-/react-emoji-0.4.4.tgz",
"integrity": "sha512-NQUk+QgF3af2poGioW9Dv6kQg9nJCEZVxRsYRYLa1H2XTelEkLVMeeTNU8Y5cMjQRuVnAfl7TzJ4zSix/qxDiQ==",
"license": "MIT",
"dependencies": {
"emoji-annotation-to-unicode": "^0.2.4",
"emoji-emoticon-to-unicode": "^0.2.2",
"escape-string-regexp": "^1.0.3",
"lodash.compact": "^3.0.0",
"object-assign": "^2.0.0"
}
},
"node_modules/react-emoji-picker": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/react-emoji-picker/-/react-emoji-picker-1.0.13.tgz",
"integrity": "sha512-nLcVgNb3Iok9Jy5frAPJoflAbHKg9Df+UZuhYVZ3bK12A2k9nFzmQyI2apTvMPC2r4h/KpHepfK10siMdqKR4g==",
"license": "ISC",
"dependencies": {
"react": "^0.14.3",
"react-emoji": "^0.4.1"
}
},
"node_modules/react-emoji-picker/node_modules/react": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/react/-/react-0.14.10.tgz",
"integrity": "sha512-yxMw5aorZG4qsLVBfjae4wGFvd5708DhcxaXLJ3IOTgr1TCs8k9+ZheGgLGr5OfwWMhSahNbGvvoEDzrxVWouA==",
"license": "BSD-3-Clause",
"dependencies": {
"envify": "^3.0.0",
"fbjs": "^0.6.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-emoji/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==",
"license": "MIT",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/react-emoji/node_modules/object-assign": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
"integrity": "sha512-CdsOUYIh5wIiozhJ3rLQgmUTgcyzFwZZrqhkKhODMoGtPKM+wt0h0CNIoauJWMsS9822EdzPsF/6mb4nLvPN5g==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-error-overlay": {
"version": "6.0.11",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
@@ -7796,6 +8152,30 @@
"node": ">=8.10.0"
}
},
"node_modules/recast": {
"version": "0.11.23",
"resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz",
"integrity": "sha512-+nixG+3NugceyR8O1bLU45qs84JgI3+8EauyRZafLgC9XbdAOIVgwV1Pe2da0YzGo62KzWoZwUpVEQf6qNAXWA==",
"license": "MIT",
"dependencies": {
"ast-types": "0.9.6",
"esprima": "~3.1.0",
"private": "~0.1.5",
"source-map": "~0.5.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/recast/node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/rechoir": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
@@ -8455,6 +8835,27 @@
"ws": "~8.17.1"
}
},
"node_modules/socket.io-adapter/node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/socket.io-parser": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
@@ -8867,6 +9268,12 @@
"tslib": "^2"
}
},
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
"license": "MIT"
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@@ -8996,6 +9403,32 @@
"node": ">=14.17"
}
},
"node_modules/ua-parser-js": {
"version": "0.7.39",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.39.tgz",
"integrity": "sha512-IZ6acm6RhQHNibSt7+c09hhvsKy9WUr4DVbeq9U8o71qxyYtJpQeDxQnMrVqnIFMLcQjHO0I9wgfO2vIahht4w==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/ua-parser-js"
},
{
"type": "paypal",
"url": "https://paypal.me/faisalman"
},
{
"type": "github",
"url": "https://github.com/sponsors/faisalman"
}
],
"license": "MIT",
"bin": {
"ua-parser-js": "script/cli.js"
},
"engines": {
"node": "*"
}
},
"node_modules/uglify-js": {
"version": "3.19.3",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
@@ -9459,6 +9892,11 @@
"node": ">=6"
}
},
"node_modules/whatwg-fetch": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-0.9.0.tgz",
"integrity": "sha512-DIuh7/cloHxHYwS/oRXGgkALYAntijL63nsgMQsNSnBj825AysosAqA2ZbYXGRqpPRiNH7335dTqV364euRpZw=="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
@@ -9540,9 +9978,10 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},

View File

@@ -5,13 +5,16 @@
"@ijl/cli": "^5.1.0",
"@types/react": "^18.3.5",
"@types/react-dom": "^18.3.0",
"emoji-mart": "^5.6.0",
"express": "^4.19.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-emoji-picker": "^1.0.13",
"react-icons": "^5.3.0",
"react-router-dom": "^6.26.1",
"styled-components": "^6.1.13",
"typescript": "^5.5.4"
"typescript": "^5.5.4",
"ws": "^8.18.0"
},
"main": "./src/index.tsx",
"scripts": {
@@ -21,5 +24,5 @@
"clean": "rimraf dist"
},
"name": "enterfront",
"version": "0.2.2"
"version": "0.2.4"
}

View File

@@ -3,8 +3,14 @@ import { BrowserRouter } from 'react-router-dom';
import { Dashboard } from './dashboard';
import { getConfigValue } from "@brojs/cli";
import './index.css'
const BASE_API_URL = getConfigValue("enterfront.api");
// fetch(`${BASE_API_URL}/books/list`)
const App = () => {
return(
<BrowserRouter>

View File

@@ -0,0 +1,43 @@
const WebSocket = require("ws");
const wss = new WebSocket.Server({ port: 8080 });
const clients = new Map();
wss.on("connection", (ws, req) => {
console.log("New client connected");
ws.on("message", (message) => {
try {
const parsedMessage = JSON.parse(message);
if (parsedMessage.type === "register") {
clients.set(parsedMessage.userId, ws);
console.log(`User registered: ${parsedMessage.userId}`);
} else if (parsedMessage.type === "message") {
const recipientWs = clients.get(parsedMessage.recipientId);
if (recipientWs) {
recipientWs.send(
JSON.stringify({
senderId: parsedMessage.senderId,
message: parsedMessage.message,
timestamp: new Date().toISOString(),
})
);
} else {
console.error(`User ${parsedMessage.recipientId} is not connected.`);
}
}
} catch (err) {
console.error("Error processing message:", err.message);
}
});
ws.on("close", () => {
console.log("Client disconnected");
[...clients.entries()].forEach(([userId, clientWs]) => {
if (clientWs === ws) {
clients.delete(userId);
console.log(`User disconnected: ${userId}`);
}
});
});
});

View File

@@ -1,8 +1,8 @@
export default class Interlocutor {
constructor(id, name) {
this.name = name
this.id = id
}
static name;
static id;
}
constructor(id, name) {
this.name = name;
this.id = id;
}
static name;
static id;
}

View File

@@ -1,3 +1,7 @@
export default class User {
}
constructor(id, name) {
this.id = id;
this.name = name;
this.status = "online";
}
}

View File

@@ -0,0 +1,17 @@
import React from 'react';
import { URLs } from "../../__data__/urls";
import ActionButton from "./ActionButton.jsx";
const AccountButtons = (props) => {
return (
<div className="account-buttons">
<ActionButton title={"Exit"} action={props.exitHandler}/>
<ActionButton title={"Change Name"} action={props.changeNameHandler}/>
<ActionButton title={"Change Pass"} action={props.changePassHandler}/>
<a className="MyButton mclaren-regular" href={URLs.home.url}>Back</a>
</div>
);
};
export default AccountButtons;

View File

@@ -0,0 +1,11 @@
import React from 'react';
const ActionButton = (props) => {
return (
<a className="MyButton mclaren-regular" onClick={() => {
props.action()
}}>{props.title}</a>
);
};
export default ActionButton;

View File

@@ -0,0 +1,29 @@
.account-buttons {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.account-buttons a {
display: flex;
font-size: 1.5vw;
transition: color 0.2s ease-in;
width: 20vw;
margin-top: 2vw;
}
.account-buttons a:hover {
color: black;
}
@media only screen and (max-width: 800px) {
.account-buttons a {
font-size: 2.5vh;
width: 60vw;
margin-top: 3vh;
}
}

View File

@@ -43,6 +43,10 @@ const Card = (props) => {
transition: color 0.3s ease-in;
}
h2 {
margin-top: 0;
}
&:hover {
box-shadow: 0 10px 40px rgb(${hexToRgb(props.color)});
cursor: pointer;
@@ -56,7 +60,7 @@ const Card = (props) => {
flex-direction: column;
border-radius: 2vh;
padding: 3vw;
padding: 5vw;
}
`

View File

@@ -34,6 +34,8 @@
margin-left: 4vw;
margin-right: 4vw;
padding-top: 0;
}
.ChatsList {

View File

@@ -1,6 +1,7 @@
@import url("reg/index.css");
@import url("init/index.css");
@import url("home/index.css");
@import url("account/index.css");
.MyButton {
text-decoration: none;

View File

@@ -17,3 +17,16 @@
font-weight: bold;
}
@media only screen and (max-width: 800px) {
.MyButton.singleNavButton p {
font-size: 2.5vh;
}
.MyButton.singleNavButton {
min-width: 60vw;
border-radius: 30vh;
margin-top: 3vh;
}
}

View File

@@ -1,25 +1,25 @@
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import React from "react";
import { Routes, Route } from "react-router-dom";
import { URLs } from './__data__/urls';
import { URLs } from "./__data__/urls";
import Home from './pages/Home.jsx'
import Init from './pages/Init.jsx'
import Account from './pages/Account.jsx'
import Chat from './pages/Chat.jsx'
import SignIn from './pages/SignIn.jsx'
import SignUp from './pages/SignUp.jsx'
import Home from "./pages/Home.jsx";
import Init from "./pages/Init.jsx";
import Account from "./pages/Account.jsx";
import Chat from "./pages/Chat.jsx";
import SignIn from "./pages/SignIn.jsx";
import SignUp from "./pages/SignUp.jsx";
export const Dashboard = () => {
return (
<Routes>
<Route path={URLs.baseUrl} element={<Init/>}/>
<Route path={URLs.home.url} element={<Home/>}/>
<Route path={URLs.chat.url} element={<Chat/>}/>
<Route path={URLs.auth.url} element={<SignIn/>}/>
<Route path={URLs.reg.url} element={<SignUp/>}/>
<Route path={URLs.account.url} element={<Account/>}/>
<Route path="*" element={<h1>404 page not found</h1>}/>
<Route path={URLs.baseUrl} element={<Init />} />
<Route path={URLs.home.url} element={<Home />} />
<Route path={URLs.chat.url} element={<Chat />} />
<Route path={URLs.auth.url} element={<SignIn />} />
<Route path={URLs.reg.url} element={<SignUp />} />
<Route path={URLs.account.url} element={<Account />} />
<Route path="*" element={<h1>404 page not found</h1>} />
</Routes>
);
};

View File

@@ -1,9 +1,22 @@
import React from "react";
import AccountButtons from "../components/account/AccountButtons.jsx";
import userIcon from "../../images/user.svg";
const Account = () => {
return (
<h1>Account</h1>
)
}
const exitHandler = () => {}
const changeNameHandler = () => {}
const changePassHandler = () => {}
export default Account;
return (
<div className="account-items">
<img src={userIcon} alt="user" />
<AccountButtons
exitHandler={exitHandler}
changeNameHandler={changeNameHandler}
changePassHandler={changePassHandler}
/>
</div>
);
};
export default Account;

View File

@@ -1,20 +1,212 @@
import React, {useEffect, useState} from 'react';
import React, { useEffect, useState, useRef } from "react";
import { useNavigate } from "react-router-dom";
import "./css/Chat.css";
import { FaPaperPlane, FaSmile } from "react-icons/fa";
const emojis = [
"😀",
"😁",
"😂",
"🤣",
"😃",
"😄",
"😅",
"😆",
"😉",
"😊",
"😋",
"😎",
"😍",
"😘",
"🥰",
"😗",
"😙",
"😚",
"🙂",
"🤗",
"🤩",
"🤔",
"😐",
"😑",
"😶",
"🙄",
"😏",
"😣",
"😥",
"😮",
"🤐",
"😯",
"😪",
"😫",
"😴",
"😌",
"😛",
"😜",
"🤪",
"🤨",
"😝",
"🤑",
"😒",
"😓",
"😔",
"😕",
"😖",
"😞",
"😟",
"😠",
"😡",
"🤬",
"😱",
"😨",
"😧",
"😇",
"🥳",
"🥺",
"😻",
"😼",
"😽",
"🙈",
"🙉",
"🙊",
"💀",
"👻",
"👽",
];
const Chat = () => {
const [interlocutorId, setInterlocutorId] = useState(0); // State to hold the interlocutorId
const [interlocutorId, setInterlocutorId] = useState(0);
const [messages, setMessages] = useState([]);
const [newMessage, setNewMessage] = useState("");
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
const socket = useRef(null);
const chatRef = useRef(null);
const navigate = useNavigate();
function getInterlocutorId() {
const id = localStorage.getItem('interlocutorId');
return id ? id : 0;
useEffect(() => {
const id = parseInt(localStorage.getItem("interlocutorId"), 10) || 0;
setInterlocutorId(id);
socket.current = new WebSocket("ws://localhost:8080");
socket.current.onopen = () => {
console.log("WebSocket connected");
socket.current.send(
JSON.stringify({ type: "register", userId: "yourUserId" })
);
};
socket.current.onmessage = (event) => {
const receivedData = JSON.parse(event.data);
setMessages((prev) => [...prev, receivedData]);
};
socket.current.onerror = (event) => {
console.error("WebSocket error observed:", event);
};
socket.current.onclose = () => {
console.log("WebSocket closed");
};
return () => {
socket.current.close();
};
}, []);
useEffect(() => {
if (chatRef.current) {
chatRef.current.scrollTop = chatRef.current.scrollHeight;
}
}, [messages]);
useEffect(() => {
const id = getInterlocutorId();
setInterlocutorId(id);
}, []);
const sendMessage = () => {
if (newMessage.trim()) {
const messageData = {
type: "message",
senderId: "yourUserId",
recipientId: interlocutorId,
message: newMessage,
timestamp: new Date().toLocaleTimeString(),
};
socket.current.send(JSON.stringify(messageData));
setMessages((prev) => [...prev, messageData]);
setNewMessage("");
}
};
const handleKeyPress = (e) => {
if (e.key === "Enter") {
sendMessage();
}
};
const handleEmojiSelect = (emoji) => {
setNewMessage((prev) => prev + emoji);
setShowEmojiPicker(false);
};
return (
<h2>Chat with ... (id = {interlocutorId})</h2>
<div className="chat-container">
<div className="chat-header">
<h2>Chat with ... (id = {interlocutorId})</h2>
<button
onClick={() => navigate("/enterfront/home")}
className="home-button"
>
Home
</button>{" "}
{}
</div>
<div className="chat-messages" ref={chatRef}>
{messages.map((msg, index) => (
<div
key={index}
className={`message-bubble ${
msg.senderId === "yourUserId" ? "sent" : "received"
}`}
>
<div className="message-content">
<b>{msg.senderId === "yourUserId" ? "You" : "Interlocutor"}:</b>{" "}
{msg.message}
</div>
<span className="message-timestamp">{msg.timestamp}</span>
</div>
))}
</div>
<div className="chat-input-container">
<input
type="text"
value={newMessage}
onChange={(e) => setNewMessage(e.target.value)}
placeholder="Type a message..."
className="chat-input"
onKeyPress={handleKeyPress}
/>
<button
className="emoji-button"
onClick={() => setShowEmojiPicker((prev) => !prev)}
>
<FaSmile />
</button>
<button onClick={sendMessage} className="send-button">
<FaPaperPlane />
</button>
{showEmojiPicker && (
<div className="emoji-picker">
{emojis.map((emoji, index) => (
<span
key={index}
className="emoji"
onClick={() => handleEmojiSelect(emoji)}
style={{ cursor: "pointer", padding: "5px" }}
>
{emoji}
</span>
))}
</div>
)}
</div>
</div>
);
};

145
src/pages/css/Chat.css Normal file
View File

@@ -0,0 +1,145 @@
.chat-container {
display: flex;
flex-direction: column;
width: 100%;
max-width: 600px;
margin: auto;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
background-color: #f9f9f9;
}
.chat-header {
padding: 10px;
background-color: #007bff;
color: white;
text-align: center;
}
.chat-messages {
display: flex;
flex-direction: column;
flex-grow: 1;
padding: 10px;
overflow-y: auto;
background-color: #fff;
}
.message-bubble {
margin: 5px;
padding: 10px 15px;
border-radius: 10px;
max-width: 70%;
word-wrap: break-word;
display: inline-block;
}
.sent {
background-color: #007bff;
color: white;
align-self: flex-end;
text-align: right;
margin-left: auto;
}
.received {
background-color: #f1f0f0;
align-self: flex-start;
text-align: left;
margin-right: auto;
}
.message-content {
font-size: 14px;
margin: 0;
padding: 0;
}
.message-timestamp {
font-size: 10px;
color: #999;
margin-top: 5px;
display: block;
}
.chat-input-container {
display: flex;
padding: 10px;
border-top: 1px solid #ddd;
background-color: #f0f0f0;
}
.chat-input {
flex-grow: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 20px;
font-size: 14px;
outline: none;
}
.send-button,
.emoji-button {
background-color: transparent;
border: none;
font-size: 20px;
margin-left: 10px;
cursor: pointer;
transition: color 0.3s;
}
.send-button:hover,
.emoji-button:hover {
color: #0056b3;
}
.send-button {
color: #007bff;
}
.emoji-button {
color: #f0c040;
}
.chat-input:focus {
border-color: #007bff;
}
.emoji-picker {
position: absolute;
bottom: 60px;
right: 10px;
z-index: 10;
background-color: white;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
display: flex;
flex-wrap: wrap;
max-width: 200px;
}
.emoji {
font-size: 24px;
cursor: pointer;
transition: transform 0.2s;
}
.emoji:hover {
transform: scale(1.2);
}
.home-button {
background-color: #4caf50;
color: white;
padding: 10px 15px;
border: none;
border-radius: 5px;
cursor: pointer;
margin-left: auto;
}
.home-button:hover {
background-color: #45a049;
}

12
src/pages/css/account.css Normal file
View File

@@ -0,0 +1,12 @@
.account-items {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: 5vw;
}
.account-items img {
margin-bottom: 1vw;
}

View File

@@ -1,3 +1,4 @@
@import url("css/init.css");
@import url("css/home.css");
@import url("css/input.css");
@import url("css/input.css");
@import url("css/account.css");

View File

@@ -0,0 +1,6 @@
{
"content": {
},
"totalElement": 0
}

View File

@@ -0,0 +1,5 @@
{
"id": "1",
"name": "Book name",
"description": "Interesting book description"
}

36
stubs/api/books/index.js Normal file
View File

@@ -0,0 +1,36 @@
const booksRouter = require('express').Router();
module.exports = booksRouter;
const books = []
booksRouter.get('/list', (req, res) => {
res.send(require('./book-list.json'))
})
booksRouter.post('/', (req, res) => {
// body() can be used because of dev server
console.log(req.body)
books.push({
name: req.body.name,
})
res.send({
status: 200
})
})
booksRouter.get('/:id', (req, res) => {
console.log(req.params);
res.send(require('./book.json'));
// res.status(404).send()
})
booksRouter.delete('/:id', (req, res) => {
res.status(201).send({
status: 'ok'
})
})

View File

@@ -1,3 +1,8 @@
const booksRouter = require("./books");
const router = require('express').Router();
const delay = require('./middlewares/delay');
module.exports = router;
// router.use(delay(300));
router.use('/books', delay, booksRouter);

View File

@@ -0,0 +1,5 @@
const delay = (ms = 1000) => (req, res, next) => {
setTimeout(next, ms)
}
module.exports = delay