From 70860a7ab7acd60ffce8116dfb3e110b2ea3d75d Mon Sep 17 00:00:00 2001 From: Lucas Orts Date: Fri, 9 Aug 2024 14:29:20 +0200 Subject: [PATCH] add alert and theme #60 --- .../api/handlers/authenticateUserHandler.js | 34 +- .../ponies/api/handlers/createPostHandler.js | 17 +- .../ponies/api/handlers/deletePostHandler.js | 17 +- .../api/handlers/getAllFavPostsHandler.js | 17 +- .../getAllFollowingUserPostsHandler.js | 16 +- .../ponies/api/handlers/getAllPostsHandler.js | 17 +- .../ponies/api/handlers/getUserNameHandler.js | 19 +- staff/lucas-orts/ponies/api/handlers/index.js | 4 +- .../api/handlers/registerUserHandler.js | 13 +- .../api/handlers/searchPosts.Handler.js | 13 + .../api/handlers/toggleFavPostHandler.js | 17 +- .../api/handlers/toggleFollowUserHandler.js | 19 +- .../api/handlers/toggleLikePostHandler.js | 17 +- .../api/handlers/updatePostCaptionHandler.js | 15 +- staff/lucas-orts/ponies/api/index.js | 19 +- .../ponies/api/middlewares/jwtVerifier.js | 4 +- .../ponies/api/test/authenticate-user.sh | 2 +- .../lucas-orts/ponies/api/test/create-post.sh | 2 +- .../lucas-orts/ponies/api/test/delete-post.sh | 2 +- .../ponies/api/test/get-fav-posts.sh | 2 +- .../ponies/api/test/get-following-posts.sh | 2 +- staff/lucas-orts/ponies/api/test/get-posts.sh | 2 +- .../ponies/api/test/get-user-name.sh | 2 +- .../ponies/api/test/search-posts.sh | 1 + .../ponies/api/test/toggle-fav-post.sh | 2 +- .../ponies/api/test/toggle-follow-user.sh | 2 +- .../ponies/api/test/toggle-like-post.sh | 2 +- .../ponies/app/.vite/deps/_metadata.json | 8 + .../ponies/app/.vite/deps/package.json | 3 + staff/lucas-orts/ponies/app/index.css | 31 +- staff/lucas-orts/ponies/app/index.html | 2 +- staff/lucas-orts/ponies/app/index.jsx | 3 +- .../lucas-orts/ponies/app/logic/createPost.js | 51 +- .../lucas-orts/ponies/app/logic/deletePost.js | 38 +- .../ponies/app/logic/getAllFavPosts.js | 41 +- .../app/logic/getAllFollowingUserPosts.js | 41 +- .../ponies/app/logic/getAllPosts.js | 41 +- .../lucas-orts/ponies/app/logic/getUserId.js | 7 + .../ponies/app/logic/getUserName.js | 44 +- staff/lucas-orts/ponies/app/logic/index.js | 10 +- .../lucas-orts/ponies/app/logic/loginUser.js | 54 +- .../ponies/app/logic/registerUser.js | 54 +- .../ponies/app/logic/searchColors.js | 24 + .../ponies/app/logic/searchPosts.js | 30 + .../ponies/app/logic/toggleFavPost.js | 38 +- .../ponies/app/logic/toggleFollowUser.js | 38 +- .../ponies/app/logic/toggleLikePost.js | 38 +- .../ponies/app/logic/updatePostCaption.js | 51 +- staff/lucas-orts/ponies/app/package-lock.json | 1143 ++++++++++++++++- staff/lucas-orts/ponies/app/package.json | 6 +- staff/lucas-orts/ponies/app/postcss.config.js | 6 + .../lucas-orts/ponies/app/tailwind.config.js | 21 + staff/lucas-orts/ponies/app/views/App.jsx | 51 +- staff/lucas-orts/ponies/app/views/Home.jsx | 52 - .../ponies/app/views/common/Alert.jsx | 17 + .../ponies/app/views/common/Confirm.jsx | 18 + .../ponies/app/views/components/Button.css | 9 - .../ponies/app/views/components/Button.jsx | 5 - .../ponies/app/views/components/Container.css | 26 - .../ponies/app/views/components/Container.jsx | 5 - .../ponies/app/views/components/Form.css | 9 - .../ponies/app/views/components/Form.jsx | 6 - .../ponies/app/views/components/Heading.css | 3 - .../ponies/app/views/components/Heading.jsx | 8 - .../ponies/app/views/components/Image.css | 3 - .../ponies/app/views/components/Image.jsx | 5 - .../ponies/app/views/components/Input.css | 4 - .../ponies/app/views/components/Input.jsx | 7 - .../ponies/app/views/components/Label.css | 3 - .../ponies/app/views/components/Label.jsx | 7 - .../ponies/app/views/components/Link.jsx | 5 - .../ponies/app/views/components/Paragraph.css | 3 - .../ponies/app/views/components/Paragraph.jsx | 7 - .../ponies/app/views/components/Time.css | 7 - .../ponies/app/views/components/Time.jsx | 7 - staff/lucas-orts/ponies/app/views/context.js | 5 + .../ponies/app/views/home/Avatar.css | 6 - .../ponies/app/views/home/Avatar.jsx | 12 +- .../ponies/app/views/home/CreatePost.css | 9 - .../ponies/app/views/home/CreatePost.jsx | 61 +- .../ponies/app/views/home/FavsPostList.jsx | 119 +- .../app/views/home/FollowingPostList.jsx | 117 +- .../ponies/app/views/home/Footer.css | 11 - .../ponies/app/views/home/Footer.jsx | 11 +- .../ponies/app/views/home/Header.css | 14 - .../ponies/app/views/home/Header.jsx | 30 +- .../lucas-orts/ponies/app/views/home/Post.css | 4 - .../lucas-orts/ponies/app/views/home/Post.jsx | 119 +- .../ponies/app/views/home/PostList.css | 5 - .../ponies/app/views/home/PostList.jsx | 118 +- .../ponies/app/views/home/ResultsPostList.jsx | 70 + .../ponies/app/views/home/Search.jsx | 48 + .../ponies/app/views/home/index.jsx | 62 + .../ponies/app/views/library/Button.jsx | 3 + .../views/{components => library}/Button1.jsx | 6 +- .../views/{components => library}/Button2.jsx | 10 +- .../ponies/app/views/library/Container.jsx | 3 + .../ponies/app/views/library/Form.jsx | 3 + .../ponies/app/views/library/Heading.jsx | 5 + .../ponies/app/views/library/Hello.jsx | 7 + .../ponies/app/views/library/Image.jsx | 3 + .../ponies/app/views/library/Input.jsx | 3 + .../ponies/app/views/library/Label.jsx | 3 + .../ponies/app/views/library/Link.jsx | 3 + .../ponies/app/views/library/Paragraph.jsx | 3 + .../ponies/app/views/library/Results.jsx | 34 + .../ponies/app/views/library/Search.jsx | 27 + .../app/views/library/SearchResults.jsx | 7 + .../ponies/app/views/library/Time.jsx | 3 + .../app/views/{Login.jsx => login/index.jsx} | 159 ++- .../{Register.jsx => register/index.jsx} | 197 ++- staff/lucas-orts/ponies/cor/data/models.js | 18 +- .../ponies/cor/logic/authenticateUser.js | 29 +- .../ponies/cor/logic/authenticateUser.test.js | 18 +- .../lucas-orts/ponies/cor/logic/createPost.js | 23 +- .../ponies/cor/logic/createPost.test.js | 17 +- .../lucas-orts/ponies/cor/logic/deletePost.js | 41 +- .../ponies/cor/logic/deletePost.test.js | 20 +- .../ponies/cor/logic/getAllFavPosts.js | 83 +- .../ponies/cor/logic/getAllFavPosts.test.js | 20 +- .../cor/logic/getAllFollowingUserPosts.js | 82 +- .../logic/getAllFollowingUserPosts.test.js | 18 +- .../ponies/cor/logic/getAllPosts.js | 81 +- .../ponies/cor/logic/getAllPosts.test.js | 20 +- .../ponies/cor/logic/getUserName.js | 34 +- .../ponies/cor/logic/getUserName.test.js | 21 +- staff/lucas-orts/ponies/cor/logic/index.js | 4 +- .../ponies/cor/logic/registerUser.js | 57 +- .../ponies/cor/logic/registerUser.test.js | 18 +- .../ponies/cor/logic/searchPosts.js | 46 + .../ponies/cor/logic/searchPosts.test.js | 10 + .../ponies/cor/logic/toggleFavPost.js | 32 +- .../ponies/cor/logic/toggleFavPost.test.js | 20 +- .../ponies/cor/logic/toggleFollowUser.js | 38 +- .../ponies/cor/logic/toggleFollowUser.test.js | 19 +- .../ponies/cor/logic/toggleLikePost.js | 55 +- .../ponies/cor/logic/toggleLikePost.test.js | 18 +- .../ponies/cor/logic/updatePostCaption.js | 37 +- .../cor/logic/updatePostCaption.test.js | 19 +- staff/lucas-orts/ponies/cor/package-lock.json | 8 +- staff/lucas-orts/ponies/cor/package.json | 2 +- 141 files changed, 2691 insertions(+), 1886 deletions(-) create mode 100644 staff/lucas-orts/ponies/api/handlers/searchPosts.Handler.js create mode 100644 staff/lucas-orts/ponies/api/test/search-posts.sh create mode 100644 staff/lucas-orts/ponies/app/.vite/deps/_metadata.json create mode 100644 staff/lucas-orts/ponies/app/.vite/deps/package.json create mode 100644 staff/lucas-orts/ponies/app/logic/getUserId.js create mode 100644 staff/lucas-orts/ponies/app/logic/searchColors.js create mode 100644 staff/lucas-orts/ponies/app/logic/searchPosts.js create mode 100644 staff/lucas-orts/ponies/app/postcss.config.js create mode 100644 staff/lucas-orts/ponies/app/tailwind.config.js delete mode 100644 staff/lucas-orts/ponies/app/views/Home.jsx create mode 100644 staff/lucas-orts/ponies/app/views/common/Alert.jsx create mode 100644 staff/lucas-orts/ponies/app/views/common/Confirm.jsx delete mode 100644 staff/lucas-orts/ponies/app/views/components/Button.css delete mode 100644 staff/lucas-orts/ponies/app/views/components/Button.jsx delete mode 100644 staff/lucas-orts/ponies/app/views/components/Container.css delete mode 100644 staff/lucas-orts/ponies/app/views/components/Container.jsx delete mode 100644 staff/lucas-orts/ponies/app/views/components/Form.css delete mode 100644 staff/lucas-orts/ponies/app/views/components/Form.jsx delete mode 100644 staff/lucas-orts/ponies/app/views/components/Heading.css delete mode 100644 staff/lucas-orts/ponies/app/views/components/Heading.jsx delete mode 100644 staff/lucas-orts/ponies/app/views/components/Image.css delete mode 100644 staff/lucas-orts/ponies/app/views/components/Image.jsx delete mode 100644 staff/lucas-orts/ponies/app/views/components/Input.css delete mode 100644 staff/lucas-orts/ponies/app/views/components/Input.jsx delete mode 100644 staff/lucas-orts/ponies/app/views/components/Label.css delete mode 100644 staff/lucas-orts/ponies/app/views/components/Label.jsx delete mode 100644 staff/lucas-orts/ponies/app/views/components/Link.jsx delete mode 100644 staff/lucas-orts/ponies/app/views/components/Paragraph.css delete mode 100644 staff/lucas-orts/ponies/app/views/components/Paragraph.jsx delete mode 100644 staff/lucas-orts/ponies/app/views/components/Time.css delete mode 100644 staff/lucas-orts/ponies/app/views/components/Time.jsx create mode 100644 staff/lucas-orts/ponies/app/views/context.js delete mode 100644 staff/lucas-orts/ponies/app/views/home/Avatar.css delete mode 100644 staff/lucas-orts/ponies/app/views/home/CreatePost.css delete mode 100644 staff/lucas-orts/ponies/app/views/home/Footer.css delete mode 100644 staff/lucas-orts/ponies/app/views/home/Header.css delete mode 100644 staff/lucas-orts/ponies/app/views/home/Post.css delete mode 100644 staff/lucas-orts/ponies/app/views/home/PostList.css create mode 100644 staff/lucas-orts/ponies/app/views/home/ResultsPostList.jsx create mode 100644 staff/lucas-orts/ponies/app/views/home/Search.jsx create mode 100644 staff/lucas-orts/ponies/app/views/home/index.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Button.jsx rename staff/lucas-orts/ponies/app/views/{components => library}/Button1.jsx (98%) rename staff/lucas-orts/ponies/app/views/{components => library}/Button2.jsx (97%) create mode 100644 staff/lucas-orts/ponies/app/views/library/Container.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Form.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Heading.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Hello.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Image.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Input.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Label.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Link.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Paragraph.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Results.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Search.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/SearchResults.jsx create mode 100644 staff/lucas-orts/ponies/app/views/library/Time.jsx rename staff/lucas-orts/ponies/app/views/{Login.jsx => login/index.jsx} (59%) rename staff/lucas-orts/ponies/app/views/{Register.jsx => register/index.jsx} (55%) create mode 100644 staff/lucas-orts/ponies/cor/logic/searchPosts.js create mode 100644 staff/lucas-orts/ponies/cor/logic/searchPosts.test.js diff --git a/staff/lucas-orts/ponies/api/handlers/authenticateUserHandler.js b/staff/lucas-orts/ponies/api/handlers/authenticateUserHandler.js index bf77708dd..fe5607b9e 100644 --- a/staff/lucas-orts/ponies/api/handlers/authenticateUserHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/authenticateUserHandler.js @@ -1,7 +1,7 @@ import jwt from 'jsonwebtoken' -import { logic } from '../../cor/index.js' -import { errors } from '../../com/index.js' +import { logic } from 'cor' +import { errors } from 'com' const { SessionError } = errors @@ -9,23 +9,19 @@ export default (req, res, next) => { const { username, password } = req.body try { - logic.authenticateUser(username, password, error => { - if (error) { - next(error) - - return - } - - jwt.sign({ sub: username }, process.env.JWT_SECRET, (error, token) => { - if (error) { - next(new SessionError(error.message)) - - return - } - - res.json(token) - }) - }) + logic.authenticateUser(username, password) + .then(userId => + jwt.sign({ sub: userId }, process.env.JWT_SECRET, (error, token) => { + if (error) { + next(new SessionError(error.message)) + + return + } + + res.json(token) + }) + ) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/handlers/createPostHandler.js b/staff/lucas-orts/ponies/api/handlers/createPostHandler.js index 8dd228c01..053a49870 100644 --- a/staff/lucas-orts/ponies/api/handlers/createPostHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/createPostHandler.js @@ -1,20 +1,13 @@ -import { logic } from '../../cor/index.js' +import { logic } from 'cor' export default (req, res, next) => { - const { username } = req + const { userId } = req const { image, caption } = req.body - try { - logic.createPost(username, image, caption, error => { - if (error) { - next(error) - - return - } - - res.status(201).send() - }) + logic.createPost(userId, image, caption) + .then(() => res.status(201).send()) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/handlers/deletePostHandler.js b/staff/lucas-orts/ponies/api/handlers/deletePostHandler.js index 351e7ace3..526d9fbea 100644 --- a/staff/lucas-orts/ponies/api/handlers/deletePostHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/deletePostHandler.js @@ -1,20 +1,13 @@ -import { logic } from '../../cor/index.js' +import { logic } from 'cor' export default (req, res, next) => { - const { username } = req + const { userId } = req const { postId } = req.params - try { - logic.deletePost(username, postId, error => { - if (error) { - next(error) - - return - } - - res.status(204).send() - }) + logic.deletePost(userId, postId) + .then(() => res.status(204).send()) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/handlers/getAllFavPostsHandler.js b/staff/lucas-orts/ponies/api/handlers/getAllFavPostsHandler.js index 6e83a910d..5f59da806 100644 --- a/staff/lucas-orts/ponies/api/handlers/getAllFavPostsHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/getAllFavPostsHandler.js @@ -1,18 +1,11 @@ -import { logic } from '../../cor/index.js' +import { logic } from 'cor' export default (req, res, next) => { - const { username } = req - + const { userId } = req try { - logic.getAllFavPosts(username, (error, posts) => { - if (error) { - next(error) - - return - } - - res.json(posts) - }) + logic.getAllFavPosts(userId) + .then(posts => res.json(posts)) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/handlers/getAllFollowingUserPostsHandler.js b/staff/lucas-orts/ponies/api/handlers/getAllFollowingUserPostsHandler.js index 8eb35b425..5884e2efe 100644 --- a/staff/lucas-orts/ponies/api/handlers/getAllFollowingUserPostsHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/getAllFollowingUserPostsHandler.js @@ -1,18 +1,12 @@ -import { logic } from '../../cor/index.js' +import { logic } from 'cor' export default (req, res, next) => { - const { username } = req + const { userId } = req try { - logic.getAllFollowingUserPosts(username, (error, posts) => { - if (error) { - next(error) - - return - } - - res.json(posts) - }) + logic.getAllFollowingUserPosts(userId) + .then(posts => res.json(posts)) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/handlers/getAllPostsHandler.js b/staff/lucas-orts/ponies/api/handlers/getAllPostsHandler.js index 4b128af79..c6e1325d7 100644 --- a/staff/lucas-orts/ponies/api/handlers/getAllPostsHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/getAllPostsHandler.js @@ -1,18 +1,11 @@ -import { logic } from '../../cor/index.js' +import { logic } from 'cor' export default (req, res, next) => { - const { username } = req - + const { userId } = req try { - logic.getAllPosts(username, (error, posts) => { - if (error) { - next(error) - - return - } - - res.json(posts) - }) + logic.getAllPosts(userId) + .then(posts => res.json(posts)) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/handlers/getUserNameHandler.js b/staff/lucas-orts/ponies/api/handlers/getUserNameHandler.js index d57b8edb5..2b7d1e67c 100644 --- a/staff/lucas-orts/ponies/api/handlers/getUserNameHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/getUserNameHandler.js @@ -1,20 +1,13 @@ -import { logic } from '../../cor/index.js' +import { logic } from 'cor' export default (req, res, next) => { - const { username } = req - - const { targetUsername } = req.params + const { userId } = req + const { targetUserId } = req.params try { - logic.getUserName(username, targetUsername, (error, name) => { - if (error) { - next(error) - - return - } - - res.json(name) - }) + logic.getUserName(userId, targetUserId) + .then(name => res.json(name)) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/handlers/index.js b/staff/lucas-orts/ponies/api/handlers/index.js index 982371aa0..f7557ef97 100644 --- a/staff/lucas-orts/ponies/api/handlers/index.js +++ b/staff/lucas-orts/ponies/api/handlers/index.js @@ -10,6 +10,7 @@ import toggleLikePostHandler from './toggleLikePostHandler.js' import toggleFavPostHandler from './toggleFavPostHandler.js' import toggleFollowUserHandler from './toggleFollowUserHandler.js' import updatePostCaptionHandler from './updatePostCaptionHandler.js' +import searchPostsHandler from './searchPosts.Handler.js' export { registerUserHandler, @@ -23,5 +24,6 @@ export { toggleLikePostHandler, toggleFavPostHandler, toggleFollowUserHandler, - updatePostCaptionHandler + updatePostCaptionHandler, + searchPostsHandler } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/handlers/registerUserHandler.js b/staff/lucas-orts/ponies/api/handlers/registerUserHandler.js index 84caf4ffc..5b6a8b697 100644 --- a/staff/lucas-orts/ponies/api/handlers/registerUserHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/registerUserHandler.js @@ -2,17 +2,10 @@ import { logic } from 'cor' export default (req, res, next) => { const { name, surname, email, username, password, passwordRepeat } = req.body - try { - logic.registerUser(name, surname, email, username, password, passwordRepeat, error => { - if (error) { - next(error) - - return - } - - res.status(201).send() - }) + logic.registerUser(name, surname, email, username, password, passwordRepeat) + .then(() => res.status(201).send()) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/handlers/searchPosts.Handler.js b/staff/lucas-orts/ponies/api/handlers/searchPosts.Handler.js new file mode 100644 index 000000000..5d893e4ae --- /dev/null +++ b/staff/lucas-orts/ponies/api/handlers/searchPosts.Handler.js @@ -0,0 +1,13 @@ +import { logic } from 'cor' + +export default (req, res, next) => { + const { userId, query: { q } } = req + + try { + logic.searchPosts(userId, q) + .then(posts => res.json(posts)) + .catch(error => next(error)) + } catch (error) { + next(error) + } +} \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/handlers/toggleFavPostHandler.js b/staff/lucas-orts/ponies/api/handlers/toggleFavPostHandler.js index 07ca32d8c..ba54df4ab 100644 --- a/staff/lucas-orts/ponies/api/handlers/toggleFavPostHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/toggleFavPostHandler.js @@ -1,20 +1,13 @@ -import { logic } from '../../cor/index.js' +import { logic } from 'cor' export default (req, res, next) => { - const { username } = req + const { userId } = req const { postId } = req.params - try { - logic.toggleFavPost(username, postId, error => { - if (error) { - next(error) - - return - } - - res.status(204).send() - }) + logic.toggleFavPost(userId, postId) + .then(() => res.status(204).send()) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/handlers/toggleFollowUserHandler.js b/staff/lucas-orts/ponies/api/handlers/toggleFollowUserHandler.js index e0a6a820b..70606beb0 100644 --- a/staff/lucas-orts/ponies/api/handlers/toggleFollowUserHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/toggleFollowUserHandler.js @@ -1,20 +1,13 @@ -import { logic } from '../../cor/index.js' +import { logic } from 'cor' export default (req, res, next) => { - const { username } = req - - const { targetUsername } = req.params + const { userId } = req + const { targetUserId } = req.params try { - logic.toggleFollowUser(username, targetUsername, error => { - if (error) { - next(error) - - return - } - - res.status(204).send() - }) + logic.toggleFollowUser(userId, targetUserId) + .then(() => res.status(204).send()) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/handlers/toggleLikePostHandler.js b/staff/lucas-orts/ponies/api/handlers/toggleLikePostHandler.js index ffe5d90d3..e28c33f7b 100644 --- a/staff/lucas-orts/ponies/api/handlers/toggleLikePostHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/toggleLikePostHandler.js @@ -1,20 +1,13 @@ -import { logic } from '../../cor/index.js' +import { logic } from 'cor' export default (req, res, next) => { - const { username } = req + const { userId } = req const { postId } = req.params - try { - logic.toggleLikePost(username, postId, error => { - if (error) { - next(error) - - return - } - - res.status(204).send() - }) + logic.toggleLikePost(userId, postId) + .then(() => res.status(204).send()) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/handlers/updatePostCaptionHandler.js b/staff/lucas-orts/ponies/api/handlers/updatePostCaptionHandler.js index 352afc65a..cf91ae1cb 100644 --- a/staff/lucas-orts/ponies/api/handlers/updatePostCaptionHandler.js +++ b/staff/lucas-orts/ponies/api/handlers/updatePostCaptionHandler.js @@ -1,22 +1,15 @@ import { logic } from 'cor' export default (req, res, next) => { - const { username } = req + const { userId } = req const { postId } = req.params const { caption } = req.body - try { - logic.updatePostCaption(username, postId, caption, error => { - if (error) { - next(error) - - return - } - - res.status(204).send() - }) + logic.updatePostCaption(userId, postId, caption) + .then(() => res.status(204).send()) + .catch(error => next(error)) } catch (error) { next(error) } diff --git a/staff/lucas-orts/ponies/api/index.js b/staff/lucas-orts/ponies/api/index.js index be8043a6b..3be11fd72 100644 --- a/staff/lucas-orts/ponies/api/index.js +++ b/staff/lucas-orts/ponies/api/index.js @@ -16,7 +16,8 @@ import { toggleLikePostHandler, toggleFavPostHandler, toggleFollowUserHandler, - updatePostCaptionHandler + updatePostCaptionHandler, + searchPostsHandler } from './handlers/index.js' mongoose.connect(process.env.MONGODB_URI) @@ -35,7 +36,7 @@ mongoose.connect(process.env.MONGODB_URI) api.post('/users/auth', jsonBodyParser, authenticateUserHandler) - api.get('/users/:targetUsername/name', jwtVerifier, getUserNameHandler) + api.get('/users/:targetUserId/name', jwtVerifier, getUserNameHandler) api.get('/posts', jwtVerifier, getAllPostsHandler) @@ -51,10 +52,22 @@ mongoose.connect(process.env.MONGODB_URI) api.patch('/posts/:postId/favs', jwtVerifier, toggleFavPostHandler) - api.patch('/users/:targetUsername/follows', jwtVerifier, toggleFollowUserHandler) + api.patch('/users/:targetUserId/follows', jwtVerifier, toggleFollowUserHandler) api.patch('/posts/:postId/caption', jwtVerifier, jsonBodyParser, updatePostCaptionHandler) + api.get('/posts/search', jwtVerifier, searchPostsHandler) + + api.get('/search', (req, res, next) => { + const colors = ['red', 'green', 'blue', 'violette', 'brown', 'yellow'] + + const { q } = req.query + + const filtered = colors.filter(color => color.includes(q)) + + res.json(filtered) + }) + api.use(errorHandler) api.listen(process.env.PORT, () => console.info(`API listening on PORT ${process.env.PORT}`)) diff --git a/staff/lucas-orts/ponies/api/middlewares/jwtVerifier.js b/staff/lucas-orts/ponies/api/middlewares/jwtVerifier.js index 38e9e14e3..d89bdf33a 100644 --- a/staff/lucas-orts/ponies/api/middlewares/jwtVerifier.js +++ b/staff/lucas-orts/ponies/api/middlewares/jwtVerifier.js @@ -16,9 +16,9 @@ export default (req, res, next) => { return } - const { sub: username } = payload + const { sub: userId } = payload - req.username = username + req.userId = userId next() }) diff --git a/staff/lucas-orts/ponies/api/test/authenticate-user.sh b/staff/lucas-orts/ponies/api/test/authenticate-user.sh index a93edb9c5..7bba3d433 100644 --- a/staff/lucas-orts/ponies/api/test/authenticate-user.sh +++ b/staff/lucas-orts/ponies/api/test/authenticate-user.sh @@ -1 +1 @@ -curl -v http://localhost:8080/users/auth -X POST -d '{"username":"estercolero","password":"87654321"}' \ No newline at end of file +curl -v http://localhost:8080/users/auth -X POST -d '{"username":"estercolero","password":"87654321"}' -H "Content-Type: application/json" \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/test/create-post.sh b/staff/lucas-orts/ponies/api/test/create-post.sh index 5e5a28c8a..be04fe9a7 100644 --- a/staff/lucas-orts/ponies/api/test/create-post.sh +++ b/staff/lucas-orts/ponies/api/test/create-post.sh @@ -1 +1 @@ -curl -v http://localhost:8080/posts -X POST -d '{"image":"https://media.giphy.com/media/Ty9Sg8oHghPWg/giphy.gif?cid=790b7611k1isspkgnlxqcvk07kqq26fe137qherkek4mavvf&ep=v1_gifs_trending&rid=giphy.gif&ct=g","caption":"ok"}' -H "Authorization: Basic Estercolero" \ No newline at end of file +curl -v http://localhost:8080/posts -X POST -d '{"image":"https://media.giphy.com/media/Ty9Sg8oHghPWg/giphy.gif?cid=790b7611k1isspkgnlxqcvk07kqq26fe137qherkek4mavvf&ep=v1_gifs_trending&rid=giphy.gif&ct=g","caption":"ok"}' -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmIwZWNjMmY3MmNmMzhjZjU3YjYzZjgiLCJpYXQiOjE3MjI4NzA5ODN9.UfDYqBTb26hfJuFlCoroEn-GJ-WL03SgtQFdr-8SRRI" -H "Content-Type: application/json" \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/test/delete-post.sh b/staff/lucas-orts/ponies/api/test/delete-post.sh index ca315b60d..d3ff2b481 100644 --- a/staff/lucas-orts/ponies/api/test/delete-post.sh +++ b/staff/lucas-orts/ponies/api/test/delete-post.sh @@ -1 +1 @@ -curl -v http://localhost:8080/posts/12hei66vjn1c -X DELETE -H "Authorization: Basic Tomasturbao" \ No newline at end of file +curl -v http://localhost:8080/posts/12hei66vjn1c -X DELETE -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmFmYTQ2MjFhYWNkMTQzYWRkYWRlMmQiLCJpYXQiOjE3MjI3ODcwNzJ9.zlLLJ-i0v6EVH6equ0soZZVM2pysqoIiuSFlmbqHO7Q" \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/test/get-fav-posts.sh b/staff/lucas-orts/ponies/api/test/get-fav-posts.sh index 76f6b3f2b..1492d9e62 100644 --- a/staff/lucas-orts/ponies/api/test/get-fav-posts.sh +++ b/staff/lucas-orts/ponies/api/test/get-fav-posts.sh @@ -1 +1 @@ -curl -v http://localhost:8080/posts/favs -H "Authorization: Basic Petazeta" \ No newline at end of file +curl -v http://localhost:8080/posts/favs -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmFmYTQ2MjFhYWNkMTQzYWRkYWRlMmQiLCJpYXQiOjE3MjI3ODcwNzJ9.zlLLJ-i0v6EVH6equ0soZZVM2pysqoIiuSFlmbqHO7Q" \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/test/get-following-posts.sh b/staff/lucas-orts/ponies/api/test/get-following-posts.sh index 60171e33d..d9634c4fe 100644 --- a/staff/lucas-orts/ponies/api/test/get-following-posts.sh +++ b/staff/lucas-orts/ponies/api/test/get-following-posts.sh @@ -1 +1 @@ -curl -v http://localhost:8080/posts/follows -H "Authorization: Basic Taguapo" \ No newline at end of file +curl -v http://localhost:8080/posts/follows -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmFmYTQ2MjFhYWNkMTQzYWRkYWRlMmQiLCJpYXQiOjE3MjI3ODcwNzJ9.zlLLJ-i0v6EVH6equ0soZZVM2pysqoIiuSFlmbqHO7Q" \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/test/get-posts.sh b/staff/lucas-orts/ponies/api/test/get-posts.sh index d3f075430..604bc15be 100644 --- a/staff/lucas-orts/ponies/api/test/get-posts.sh +++ b/staff/lucas-orts/ponies/api/test/get-posts.sh @@ -1 +1 @@ -curl -v http://localhost:8080/posts -H "Authorization: Basic Petazeta" \ No newline at end of file +curl -v http://localhost:8080/posts -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmFmYTQ2MjFhYWNkMTQzYWRkYWRlMmQiLCJpYXQiOjE3MjI3ODcwNzJ9.zlLLJ-i0v6EVH6equ0soZZVM2pysqoIiuSFlmbqHO7Q" \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/test/get-user-name.sh b/staff/lucas-orts/ponies/api/test/get-user-name.sh index 8f9b92855..567480f7b 100644 --- a/staff/lucas-orts/ponies/api/test/get-user-name.sh +++ b/staff/lucas-orts/ponies/api/test/get-user-name.sh @@ -1 +1 @@ -curl -v http://localhost:8080/users/Tomasturbao/name -X GET -H "Authorization: Basic Tomasturbao" \ No newline at end of file +curl -v http://localhost:8080/users/66afb08b82188b45d8eb0288/name -X GET -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmFmYjA4YjgyMTg4YjQ1ZDhlYjAyODgiLCJpYXQiOjE3MjI3OTAwNDJ9.Lxw-kws9X5_H-qTKgvYWbYDu3xG76Lk_dto-v6SYQp4" \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/test/search-posts.sh b/staff/lucas-orts/ponies/api/test/search-posts.sh new file mode 100644 index 000000000..22f1489e1 --- /dev/null +++ b/staff/lucas-orts/ponies/api/test/search-posts.sh @@ -0,0 +1 @@ +curl -v http://localhost:8080/posts/search?q=pon -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmIwZWNjMmY3MmNmMzhjZjU3YjYzZjgiLCJpYXQiOjE3MjI4NzA5ODN9.UfDYqBTb26hfJuFlCoroEn-GJ-WL03SgtQFdr-8SRRI" \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/test/toggle-fav-post.sh b/staff/lucas-orts/ponies/api/test/toggle-fav-post.sh index fdd5dbba0..58f02f281 100644 --- a/staff/lucas-orts/ponies/api/test/toggle-fav-post.sh +++ b/staff/lucas-orts/ponies/api/test/toggle-fav-post.sh @@ -1 +1 @@ -curl -v http://localhost:8080/posts/66a212db45efecc54ca44e1f/favs -X PATCH -H "Authorization: Basic Estercolero" \ No newline at end of file +curl -v http://localhost:8080/posts/66a212db45efecc54ca44e1f/favs -X PATCH -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmFmYTQ2MjFhYWNkMTQzYWRkYWRlMmQiLCJpYXQiOjE3MjI3ODcwNzJ9.zlLLJ-i0v6EVH6equ0soZZVM2pysqoIiuSFlmbqHO7Q" \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/test/toggle-follow-user.sh b/staff/lucas-orts/ponies/api/test/toggle-follow-user.sh index 6cf51f3d2..0f8372ba8 100644 --- a/staff/lucas-orts/ponies/api/test/toggle-follow-user.sh +++ b/staff/lucas-orts/ponies/api/test/toggle-follow-user.sh @@ -1 +1 @@ -curl -v http://localhost:8080/users/Petazeta/follows -X PATCH -H "Authorization: Basic Tomasturbao" \ No newline at end of file +curl -v http://localhost:8080/users/Petazeta/follows -X PATCH -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmFmYTQ2MjFhYWNkMTQzYWRkYWRlMmQiLCJpYXQiOjE3MjI3ODcwNzJ9.zlLLJ-i0v6EVH6equ0soZZVM2pysqoIiuSFlmbqHO7Q" \ No newline at end of file diff --git a/staff/lucas-orts/ponies/api/test/toggle-like-post.sh b/staff/lucas-orts/ponies/api/test/toggle-like-post.sh index c980bdeb1..c63fa4374 100644 --- a/staff/lucas-orts/ponies/api/test/toggle-like-post.sh +++ b/staff/lucas-orts/ponies/api/test/toggle-like-post.sh @@ -1 +1 @@ -curl -v http://localhost:8080/posts/4zcpc42md1w/likes -X PATCH -H "Authorization: Basic Tomasturbao" \ No newline at end of file +curl -v http://localhost:8080/posts/4zcpc42md1w/likes -X PATCH -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmFmYTQ2MjFhYWNkMTQzYWRkYWRlMmQiLCJpYXQiOjE3MjI3ODcwNzJ9.zlLLJ-i0v6EVH6equ0soZZVM2pysqoIiuSFlmbqHO7Q" \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/.vite/deps/_metadata.json b/staff/lucas-orts/ponies/app/.vite/deps/_metadata.json new file mode 100644 index 000000000..71daddb26 --- /dev/null +++ b/staff/lucas-orts/ponies/app/.vite/deps/_metadata.json @@ -0,0 +1,8 @@ +{ + "hash": "6684fc91", + "configHash": "8695704b", + "lockfileHash": "e3b0c442", + "browserHash": "e88c8ee9", + "optimized": {}, + "chunks": {} +} \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/.vite/deps/package.json b/staff/lucas-orts/ponies/app/.vite/deps/package.json new file mode 100644 index 000000000..3dbc1ca59 --- /dev/null +++ b/staff/lucas-orts/ponies/app/.vite/deps/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/staff/lucas-orts/ponies/app/index.css b/staff/lucas-orts/ponies/app/index.css index f22ede468..ef0dd9000 100644 --- a/staff/lucas-orts/ponies/app/index.css +++ b/staff/lucas-orts/ponies/app/index.css @@ -1,13 +1,26 @@ -.view { - display: flex; - flex-direction: column; - align-items: center; - gap: 1rem; - font-size: 1.1rem; +@import url('https://fonts.googleapis.com/css2?family=Neucha&display=swap'); + +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer utilities { + .clip-path-40 { + clip-path: circle(40%); + } } +@layer base { + @font-face { + font-family: 'Scatters'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(./fonts/Scatters-Demo.ttf); + } -.main { - margin-top: 3.5rem; - margin-bottom: 3rem; + html { + font-family: 'Neucha', 'Scatters', system-ui, sans-serif; + font-size: large; + } } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/index.html b/staff/lucas-orts/ponies/app/index.html index 9e94e00d2..152592f08 100644 --- a/staff/lucas-orts/ponies/app/index.html +++ b/staff/lucas-orts/ponies/app/index.html @@ -8,7 +8,7 @@ - +
diff --git a/staff/lucas-orts/ponies/app/index.jsx b/staff/lucas-orts/ponies/app/index.jsx index 73691dc06..460e72e00 100644 --- a/staff/lucas-orts/ponies/app/index.jsx +++ b/staff/lucas-orts/ponies/app/index.jsx @@ -1,8 +1,9 @@ import ReactDOM from 'react-dom/client' +import { BrowserRouter as Router } from 'react-router-dom' import App from './views/App' import './index.css' const root = ReactDOM.createRoot(document.getElementById('root')) -root.render() \ No newline at end of file +root.render() \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/createPost.js b/staff/lucas-orts/ponies/app/logic/createPost.js index 7849f166e..69d07d5ef 100644 --- a/staff/lucas-orts/ponies/app/logic/createPost.js +++ b/staff/lucas-orts/ponies/app/logic/createPost.js @@ -1,31 +1,32 @@ import { validate, errors } from 'com' -export default (image, caption, callback) => { +const { SystemError } = errors + +export default (image, caption) => { validate.image(image) validate.string(caption, 'caption') - validate.callback(callback) - - const xhr = new XMLHttpRequest - - xhr.onload = () => { - if (xhr.status === 201) { - callback(null) - - return - } - - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] - - callback(new constructor(message)) - } - - xhr.onerror = () => callback(new Error('network error')) - - xhr.open('POST', `${import.meta.env.VITE_API_URL}/posts`) - xhr.setRequestHeader('Authorization', `Bearer ${sessionStorage.token}`) - xhr.setRequestHeader('Content-Type', 'application/json') - xhr.send(JSON.stringify({ image, caption })) + return fetch(`${import.meta.env.VITE_API_URL}/posts`, { + method: 'POST', + headers: { + Authorization: `Bearer ${sessionStorage.token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ image, caption }) + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response + + if (status === 201) return + + return response.json() + .then(body => { + const { error, message } = body + + const constructor = errors[error] + + throw new constructor(message) + }) + }) } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/deletePost.js b/staff/lucas-orts/ponies/app/logic/deletePost.js index 54ae0cba9..c76579224 100644 --- a/staff/lucas-orts/ponies/app/logic/deletePost.js +++ b/staff/lucas-orts/ponies/app/logic/deletePost.js @@ -1,29 +1,29 @@ import { validate, errors } from 'com' -export default (postId, callabck) => { - validate.postId(postId) - validate.callback(callabck) - - const xhr = new XMLHttpRequest +const { SystemError } = errors - xhr.onload = () => { - if (xhr.status === 204) { - callabck(null) +export default postId => { + validate.postId(postId) - return + return fetch(`${import.meta.env.VITE_API_URL}/posts/${postId}`, { + method: 'DELETE', + headers: { + Authorization: `Bearer ${sessionStorage.token}` } + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] - - callabck(new constructor(message)) - } + if (status === 204) return - xhr.onerror = () => callabck(new Error('network error')) + return response.json() + .then(body => { + const { error, message } = body - xhr.open('DELETE', `${import.meta.env.VITE_API_URL}/posts/${postId}`) - xhr.setRequestHeader('Authorization', `Bearer ${sessionStorage.token}`) + const constructor = errors[error] - xhr.send() + throw new constructor(message) + }) + }) } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/getAllFavPosts.js b/staff/lucas-orts/ponies/app/logic/getAllFavPosts.js index 44629c1bc..9ed9c2fff 100644 --- a/staff/lucas-orts/ponies/app/logic/getAllFavPosts.js +++ b/staff/lucas-orts/ponies/app/logic/getAllFavPosts.js @@ -1,29 +1,28 @@ -import { validate, errors } from 'com' +import { errors } from 'com' -export default callback => { - validate.callback(callback) +const { SystemError } = errors - const xhr = new XMLHttpRequest - - xhr.onload = () => { - if (xhr.status === 200) { - const posts = JSON.parse(xhr.response) - - callback(null, posts) - - return +export default () => { + return fetch(`${import.meta.env.VITE_API_URL}/posts/favs`, { + headers: { + Authorization: `Bearer ${sessionStorage.token}` } + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] + if (status === 200) + return response.json() + .then(posts => posts) - callback(new constructor(message)) - } + return response.json() + .then(body => { + const { error, message } = body - xhr.onerror = () => callback(new Error('network error')) + const constructor = errors[error] - xhr.open('GET', `${import.meta.env.VITE_API_URL}/posts/favs`) - xhr.setRequestHeader('Authorization', `Bearer ${sessionStorage.token}`) - xhr.send() + throw new constructor(message) + }) + }) } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/getAllFollowingUserPosts.js b/staff/lucas-orts/ponies/app/logic/getAllFollowingUserPosts.js index 5a6043aee..92fea8939 100644 --- a/staff/lucas-orts/ponies/app/logic/getAllFollowingUserPosts.js +++ b/staff/lucas-orts/ponies/app/logic/getAllFollowingUserPosts.js @@ -1,29 +1,28 @@ -import { validate, errors } from 'com' +import { errors } from 'com' -export default callabck => { - validate.callback(callabck) +const { SystemError } = errors - const xhr = new XMLHttpRequest - - xhr.onload = () => { - if (xhr.status === 200) { - const posts = JSON.parse(xhr.response) - - callabck(null, posts) - - return +export default () => { + return fetch(`${import.meta.env.VITE_API_URL}/posts/follows`, { + headers: { + Authorization: `Bearer ${sessionStorage.token}` } + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] + if (status === 200) + return response.json() + .then(posts => posts) - callabck(new constructor(message)) - } + return response.json() + .then(body => { + const { error, message } = body - xhr.onerror = () => callabck(new Error('network error')) + const constructor = errors[error] - xhr.open('GET', `${import.meta.env.VITE_API_URL}/posts/follows`) - xhr.setRequestHeader('Authorization', `Bearer ${sessionStorage.token}`) - xhr.send() + throw new constructor(message) + }) + }) } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/getAllPosts.js b/staff/lucas-orts/ponies/app/logic/getAllPosts.js index c119ea878..e1fb18a76 100644 --- a/staff/lucas-orts/ponies/app/logic/getAllPosts.js +++ b/staff/lucas-orts/ponies/app/logic/getAllPosts.js @@ -1,29 +1,28 @@ -import { validate, errors } from 'com' +import { errors } from 'com' -export default callback => { - validate.callback(callback) +const { SystemError } = errors - const xhr = new XMLHttpRequest - - xhr.onload = () => { - if (xhr.status === 200) { - const posts = JSON.parse(xhr.response) - - callback(null, posts) - - return +export default () => { + return fetch(`${import.meta.env.VITE_API_URL}/posts`, { + headers: { + Authorization: `Bearer ${sessionStorage.token}` } + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] + if (status === 200) + return response.json() + .then(posts => posts) - callback(new constructor(message)) - } + return response.json() + .then(body => { + const { error, message } = body - xhr.onerror = () => callback(new Error('network error')) + const constructor = errors[error] - xhr.open('GET', `${import.meta.env.VITE_API_URL}/posts`) - xhr.setRequestHeader('Authorization', `Bearer ${sessionStorage.token}`) - xhr.send() + throw new constructor(message) + }) + }) } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/getUserId.js b/staff/lucas-orts/ponies/app/logic/getUserId.js new file mode 100644 index 000000000..a3c51642d --- /dev/null +++ b/staff/lucas-orts/ponies/app/logic/getUserId.js @@ -0,0 +1,7 @@ +import extractPayloadFromToken from '../util/extractPayloadFromToken' + +export default () => { + const { sub: userId } = extractPayloadFromToken(sessionStorage.token) + + return userId +} \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/getUserName.js b/staff/lucas-orts/ponies/app/logic/getUserName.js index f68b901df..51904747d 100644 --- a/staff/lucas-orts/ponies/app/logic/getUserName.js +++ b/staff/lucas-orts/ponies/app/logic/getUserName.js @@ -1,32 +1,32 @@ -import { validate, errors } from 'com' -import extractPayloadFromToken from "../util/extractPayloadFromToken" +import { errors } from 'com' -export default callback => { - validate.callback(callback) +const { SystemError } = errors - const xhr = new XMLHttpRequest +import extractPayloadFromToken from '../util/extractPayloadFromToken' - xhr.onload = () => { - if (xhr.status === 200) { - const name = JSON.parse(xhr.response) - - callback(null, name) +export default () => { + const { sub: username } = extractPayloadFromToken(sessionStorage.token) - return + return fetch(`${import.meta.env.VITE_API_URL}/users/${username}/name`, { + headers: { + Authorization: `Bearer ${sessionStorage.token}` } + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] + if (status === 200) + return response.json() + .then(name => name) - callback(new constructor(message)) - } + return response.json() + .then(body => { + const { error, message } = body - xhr.onerror = () => callback(new Error('network error')) - - const { sub: username } = extractPayloadFromToken(sessionStorage.token) + const constructor = errors[error] - xhr.open('GET', `${import.meta.env.VITE_API_URL}/users/${username}/name`) - xhr.setRequestHeader('Authorization', `Bearer ${sessionStorage.token}`) - xhr.send() + throw new constructor(message) + }) + }) } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/index.js b/staff/lucas-orts/ponies/app/logic/index.js index 7436b4c76..75fb4a10b 100644 --- a/staff/lucas-orts/ponies/app/logic/index.js +++ b/staff/lucas-orts/ponies/app/logic/index.js @@ -12,7 +12,10 @@ import toggleFavPost from './toggleFavPost' import getAllFavPosts from './getAllFavPosts' import toggleFollowUser from './toggleFollowUser' import getAllFollowingUserPosts from './getAllFollowingUserPosts' -import isUserLoggedIn from "./isUserLoggedIn" +import isUserLoggedIn from './isUserLoggedIn' +import getUserId from './getUserId' +import searchColors from './searchColors' +import searchPosts from './searchPosts' const logic = { getAllPosts, @@ -29,7 +32,10 @@ const logic = { getAllFavPosts, toggleFollowUser, getAllFollowingUserPosts, - isUserLoggedIn + isUserLoggedIn, + getUserId, + searchColors, + searchPosts } export default logic \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/loginUser.js b/staff/lucas-orts/ponies/app/logic/loginUser.js index e11e72b0d..094c24796 100644 --- a/staff/lucas-orts/ponies/app/logic/loginUser.js +++ b/staff/lucas-orts/ponies/app/logic/loginUser.js @@ -1,33 +1,33 @@ import { validate, errors } from 'com' -export default (username, password, callback) => { +const { SystemError } = errors + +export default (username, password) => { validate.username(username) validate.password(password) - validate.callback(callback) - - const xhr = new XMLHttpRequest - - xhr.onload = () => { - if (xhr.status === 200) { - const token = JSON.parse(xhr.response) - sessionStorage.token = token - - callback(null) - - return - } - - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] - - callback(new constructor(message)) - } - - xhr.onerror = () => callback(new Error('network error')) - - xhr.open('POST', `${import.meta.env.VITE_API_URL}/users/auth`) - xhr.setRequestHeader('Content-Type', 'application/json') - xhr.send(JSON.stringify({ username, password })) + return fetch(`${import.meta.env.VITE_API_URL}/users/auth`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ username, password }) + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response + + if (status === 200) + return response.json() + .then(token => sessionStorage.token = token) + + return response.json() + .then(body => { + const { error, message } = body + + const constructor = errors[error] + + throw new constructor(message) + }) + }) } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/registerUser.js b/staff/lucas-orts/ponies/app/logic/registerUser.js index d6f25c21f..f8e860fb9 100644 --- a/staff/lucas-orts/ponies/app/logic/registerUser.js +++ b/staff/lucas-orts/ponies/app/logic/registerUser.js @@ -1,33 +1,35 @@ import { validate, errors } from 'com' -export default (name, surname, email, username, password, passwordRepeat, callback) => { +const { SystemError } = errors + +export default (name, surname, email, username, password, passwordRepeat) => { validate.name(name) validate.name(surname, 'surname') validate.email(email) validate.username(username) validate.password(password) - validate.callback(callback) - - const xhr = new XMLHttpRequest - - xhr.onload = () => { - if (xhr.status === 201) { - callback(null) - - return - } - - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] - - callback(new constructor(message)) - } - - xhr.onerror = () => callback(new Error('network error')) - - xhr.open('POST', `${import.meta.env.VITE_API_URL}/users`) - xhr.setRequestHeader('Content-Type', 'application/json') - - xhr.send(JSON.stringify({ name, surname, email, username, password, passwordRepeat })) -} + validate.password(passwordRepeat, 'passwordRepeat') + + return fetch(`${import.meta.env.VITE_API_URL}/users`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ name, surname, email, username, password, passwordRepeat }) + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response + + if (status === 201) return + + return response.json() + .then(body => { + const { error, message } = body + + const constructor = errors[error] + + throw new constructor(message) + }) + }) +} \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/searchColors.js b/staff/lucas-orts/ponies/app/logic/searchColors.js new file mode 100644 index 000000000..5a8dac6ff --- /dev/null +++ b/staff/lucas-orts/ponies/app/logic/searchColors.js @@ -0,0 +1,24 @@ +import { validate, errors } from 'com' + +const { SystemError } = errors + +export default query => { + validate.string(query, 'query') + + return fetch(`${import.meta.env.VITE_API_URL}/search?q=${query}`) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response + + if (status === 200) + return response.json() + .then(colors => colors) + + return response.json() + .then(body => { + const { error, message } = body + const constructor = errors[error] + throw new constructor(message) + }) + }) +} \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/searchPosts.js b/staff/lucas-orts/ponies/app/logic/searchPosts.js new file mode 100644 index 000000000..1279e62c5 --- /dev/null +++ b/staff/lucas-orts/ponies/app/logic/searchPosts.js @@ -0,0 +1,30 @@ +import { errors, validate } from 'com' + +const { SystemError } = errors + +export default query => { + validate.string(query, 'query') + + return fetch(`${import.meta.env.VITE_API_URL}/posts/search?q=${query}`, { + headers: { + Authorization: `Bearer ${sessionStorage.token}` + } + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response + + if (status === 200) + return response.json() + .then(posts => posts) + + return response.json() + .then(body => { + const { error, message } = body + + const constructor = errors[error] + + throw new constructor(message) + }) + }) +} \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/toggleFavPost.js b/staff/lucas-orts/ponies/app/logic/toggleFavPost.js index f185cc25a..32a73edd2 100644 --- a/staff/lucas-orts/ponies/app/logic/toggleFavPost.js +++ b/staff/lucas-orts/ponies/app/logic/toggleFavPost.js @@ -1,29 +1,29 @@ import { validate, errors } from 'com' -export default (postId, callback) => { - validate.postId(postId) - validate.callback(callback) - - const xhr = new XMLHttpRequest +const { SystemError } = errors - xhr.onload = () => { - if (xhr.status === 204) { - callback(null) +export default postId => { + validate.postId(postId) - return + return fetch(`${import.meta.env.VITE_API_URL}/posts/${postId}/favs`, { + method: 'PATCH', + headers: { + Authorization: `Bearer ${sessionStorage.token}` } + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] - - callback(new constructor(message)) - } + if (status === 204) return - xhr.onerror = () => callback(new Error('network error')) + return response.json() + .then(body => { + const { error, message } = body - xhr.open('PATCH', `${import.meta.env.VITE_API_URL}/posts/${postId}/favs`) - xhr.setRequestHeader('Authorization', `Bearer ${sessionStorage.token}`) + const constructor = errors[error] - xhr.send() + throw new constructor(message) + }) + }) } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/toggleFollowUser.js b/staff/lucas-orts/ponies/app/logic/toggleFollowUser.js index 2a0dd0c9a..2e5e4e0e6 100644 --- a/staff/lucas-orts/ponies/app/logic/toggleFollowUser.js +++ b/staff/lucas-orts/ponies/app/logic/toggleFollowUser.js @@ -1,29 +1,29 @@ import { validate, errors } from 'com' -export default (username, callback) => { - validate.username(username) - validate.callback(callback) +const { SystemError } = errors - const xhr = new XMLHttpRequest +export default targetUserId => { + validate.string(targetUserId, 'targetUserId') - xhr.onload = () => { - if (xhr.status === 204) { - callback(null) - - return + return fetch(`${import.meta.env.VITE_API_URL}/users/${targetUserId}/follows`, { + method: 'PATCH', + headers: { + Authorization: `Bearer ${sessionStorage.token}` } + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] - - callback(new constructor(message)) - } + if (status === 204) return - xhr.onerror = () => callback(new Error('network error')) + return response.json() + .then(body => { + const { error, message } = body - xhr.open('PATCH', `${import.meta.env.VITE_API_URL}/users/${username}/follows`) - xhr.setRequestHeader('Authorization', `Bearer ${sessionStorage.token}`) + const constructor = errors[error] - xhr.send() + throw new constructor(message) + }) + }) } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/toggleLikePost.js b/staff/lucas-orts/ponies/app/logic/toggleLikePost.js index 104d4f513..ee09f6363 100644 --- a/staff/lucas-orts/ponies/app/logic/toggleLikePost.js +++ b/staff/lucas-orts/ponies/app/logic/toggleLikePost.js @@ -1,29 +1,29 @@ import { validate, errors } from 'com' -export default (postId, callback) => { - validate.postId(postId) - validate.callback(callback) - - const xhr = new XMLHttpRequest +const { SystemError } = errors - xhr.onload = () => { - if (xhr.status === 204) { - callback(null) +export default postId => { + validate.postId(postId) - return + return fetch(`${import.meta.env.VITE_API_URL}/posts/${postId}/likes`, { + method: 'PATCH', + headers: { + Authorization: `Bearer ${sessionStorage.token}` } + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] - - callback(new constructor(message)) - } + if (status === 204) return - xhr.onerror = () => callback(new Error('network error')) + return response.json() + .then(body => { + const { error, message } = body - xhr.open('PATCH', `${import.meta.env.VITE_API_URL}/posts/${postId}/likes`) - xhr.setRequestHeader('Authorization', `Bearer ${sessionStorage.token}`) + const constructor = errors[error] - xhr.send() + throw new constructor(message) + }) + }) } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/logic/updatePostCaption.js b/staff/lucas-orts/ponies/app/logic/updatePostCaption.js index 0ad3c8df8..66db5537a 100644 --- a/staff/lucas-orts/ponies/app/logic/updatePostCaption.js +++ b/staff/lucas-orts/ponies/app/logic/updatePostCaption.js @@ -1,31 +1,32 @@ import { validate, errors } from 'com' -export default (postId, caption, callback) => { +const { SystemError } = errors + +export default (postId, caption) => { validate.postId(postId) validate.string(caption, 'caption') - validate.callback(callback) - - const xhr = new XMLHttpRequest - - xhr.onload = () => { - if (xhr.status === 204) { - callback(null) - - return - } - - const { error, message } = JSON.parse(xhr.response) - - const constructor = errors[error] - - callback(new constructor(message)) - } - - xhr.onerror = () => callback(new Error('network error')) - - xhr.open('PATCH', `${import.meta.env.VITE_API_URL}/posts/${postId}/caption`) - xhr.setRequestHeader('Authorization', `Bearer ${sessionStorage.token}`) - xhr.setRequestHeader('Content-Type', 'application/json') - xhr.send(JSON.stringify({ caption })) + return fetch(`${import.meta.env.VITE_API_URL}/posts/${postId}/caption`, { + method: 'PATCH', + headers: { + Authorization: `Bearer ${sessionStorage.token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ caption }) + }) + .catch(error => { throw new SystemError(error.message) }) + .then(response => { + const { status } = response + + if (status === 204) return + + return response.json() + .then(body => { + const { error, message } = body + + const constructor = errors[error] + + throw new constructor(message) + }) + }) } \ No newline at end of file diff --git a/staff/lucas-orts/ponies/app/package-lock.json b/staff/lucas-orts/ponies/app/package-lock.json index 38f01d70a..6e7bdef23 100644 --- a/staff/lucas-orts/ponies/app/package-lock.json +++ b/staff/lucas-orts/ponies/app/package-lock.json @@ -10,16 +10,20 @@ "dependencies": { "com": "file:../com", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-router-dom": "^6.26.0" }, "devDependencies": { "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.1", + "autoprefixer": "^10.4.20", "eslint": "^8.57.0", "eslint-plugin-react": "^7.34.2", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", + "postcss": "^8.4.41", + "tailwindcss": "^3.4.9", "vite": "^5.3.1", "vitest": "^2.0.1" } @@ -28,6 +32,18 @@ "version": "1.0.0", "license": "ISC" }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -903,6 +919,50 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -1007,6 +1067,24 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@remix-run/router": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.0.tgz", + "integrity": "sha512-zDICCLKEwbVYTS6TjYaWtHXxkdoUvD/QXvyVZjGCsWz5vyH7aFeONlPffPdW+Y/t6KT0MgXb2Mfjun9YpWN1dA==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", @@ -1481,6 +1559,31 @@ "node": ">=4" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1648,6 +1751,43 @@ "node": ">=12" } }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -1671,6 +1811,18 @@ "dev": true, "license": "MIT" }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1682,10 +1834,22 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browserslist": { - "version": "4.23.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", - "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "funding": [ { @@ -1701,11 +1865,10 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001640", - "electron-to-chromium": "^1.4.820", - "node-releases": "^2.0.14", + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.0" }, "bin": { @@ -1755,10 +1918,19 @@ "node": ">=6" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/caniuse-lite": { - "version": "1.0.30001641", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz", - "integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==", + "version": "1.0.30001651", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", + "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", "dev": true, "funding": [ { @@ -1773,8 +1945,7 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/chai": { "version": "5.1.1", @@ -1818,6 +1989,42 @@ "node": ">= 16" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1839,6 +2046,15 @@ "resolved": "../com", "link": true }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1868,6 +2084,18 @@ "node": ">= 8" } }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -2000,6 +2228,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -2010,6 +2244,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2023,12 +2263,23 @@ "node": ">=6.0.0" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/electron-to-chromium": { - "version": "1.4.823", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.823.tgz", - "integrity": "sha512-4h+oPeAiGQOHFyUJOqpoEcPj/xxlicxBzOErVeYVMMmAiXUXsGpsFd0QXBMaUUbnD8hhSfLf9uw+MlsoIA7j5w==", - "dev": true, - "license": "ISC" + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz", + "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/es-abstract": { "version": "1.23.3", @@ -2620,6 +2871,34 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2657,6 +2936,18 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -2706,6 +2997,35 @@ "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3135,6 +3455,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -3236,6 +3568,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -3291,6 +3632,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/is-number-object": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", @@ -3495,6 +3845,30 @@ "set-function-name": "^2.0.1" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3601,6 +3975,21 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3673,6 +4062,28 @@ "dev": true, "license": "MIT" }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -3699,6 +4110,15 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -3706,6 +4126,17 @@ "dev": true, "license": "MIT" }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -3733,11 +4164,28 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, "node_modules/npm-run-path": { "version": "5.3.0", @@ -3778,6 +4226,15 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", @@ -3966,6 +4423,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4016,6 +4479,28 @@ "dev": true, "license": "MIT" }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "node_modules/pathe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", @@ -4040,6 +4525,36 @@ "dev": true, "license": "ISC" }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -4051,9 +4566,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", "dev": true, "funding": [ { @@ -4069,7 +4584,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", @@ -4079,6 +4593,150 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-import/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4209,6 +4867,57 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.0.tgz", + "integrity": "sha512-wVQq0/iFYd3iZ9H2l3N3k4PL8EEHcb0XlU2Na8nEwmiXgIUElEH6gaJDtUQxJ+JFzmIXaQjfdpcGWaM6IoQGxg==", + "dependencies": { + "@remix-run/router": "1.19.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.0.tgz", + "integrity": "sha512-RRGUIiDtLrkX3uYcFiCIxKFWMcWQGMojpYZfcstc63A1+sSnVgILGIm9gNUA6na3Fm1QuPGSBQH2EMbAZOnMsQ==", + "dependencies": { + "@remix-run/router": "1.19.0", + "react-router": "6.26.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", @@ -4542,6 +5251,71 @@ "dev": true, "license": "MIT" }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", @@ -4634,6 +5408,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-final-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", @@ -4660,6 +5447,72 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -4686,6 +5539,60 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tailwindcss": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.9.tgz", + "integrity": "sha512-1SEOvRr6sSdV5IDf9iC+NU4dhwdqzF4zKKq3sAbasUWHEM6lsMhX+eNN5gkPx1BvLFEnZQEUFbXnGj8Qlp83Pg==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4693,6 +5600,27 @@ "dev": true, "license": "MIT" }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/tinybench": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", @@ -4730,6 +5658,24 @@ "node": ">=4" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -4890,6 +5836,12 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, "node_modules/vite": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz", @@ -5159,6 +6111,133 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -5173,6 +6252,18 @@ "dev": true, "license": "ISC" }, + "node_modules/yaml": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", + "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/staff/lucas-orts/ponies/app/package.json b/staff/lucas-orts/ponies/app/package.json index 10be59f1a..629125b8c 100644 --- a/staff/lucas-orts/ponies/app/package.json +++ b/staff/lucas-orts/ponies/app/package.json @@ -12,16 +12,20 @@ "dependencies": { "com": "file:../com", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-router-dom": "^6.26.0" }, "devDependencies": { "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.1", + "autoprefixer": "^10.4.20", "eslint": "^8.57.0", "eslint-plugin-react": "^7.34.2", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", + "postcss": "^8.4.41", + "tailwindcss": "^3.4.9", "vite": "^5.3.1", "vitest": "^2.0.1" } diff --git a/staff/lucas-orts/ponies/app/postcss.config.js b/staff/lucas-orts/ponies/app/postcss.config.js new file mode 100644 index 000000000..d41ad6355 --- /dev/null +++ b/staff/lucas-orts/ponies/app/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/staff/lucas-orts/ponies/app/tailwind.config.js b/staff/lucas-orts/ponies/app/tailwind.config.js new file mode 100644 index 000000000..222a3347e --- /dev/null +++ b/staff/lucas-orts/ponies/app/tailwind.config.js @@ -0,0 +1,21 @@ +/** @type {import('tailwindcss').Config} */ + +import defaultTheme from 'tailwindcss/defaultTheme' + +export default { + content: [ + './index.html', + './view/**/*.jsx' + ], + theme: { + extend: { + fontFamily: { + scatters: ['Scatters', ...defaultTheme.fontFamily.sans], + neucha: ['Neucha', ...defaultTheme.fontFamily.sans] + }, + }, + }, + plugins: [], + darkMode: 'selector' +} + diff --git a/staff/lucas-orts/ponies/app/views/App.jsx b/staff/lucas-orts/ponies/app/views/App.jsx index ca6638714..9fee4641e 100644 --- a/staff/lucas-orts/ponies/app/views/App.jsx +++ b/staff/lucas-orts/ponies/app/views/App.jsx @@ -1,41 +1,56 @@ -import { useState } from 'react' +import { useState, useEffect } from 'react' +import { Routes, Route, useNavigate, Navigate } from 'react-router-dom' -import Login from './Login' -import Register from './Register' -import Home from './Home' +import Login from './login' +import Register from './register' +import Home from './home' +import Alert from './common/Alert' + +import { Context } from './context' import logic from '../logic' -const App = () => { - const [view, setView] = useState(logic.isUserLoggedIn() ? 'home' : 'login') +export default function App() { + const navigate = useNavigate() + + const [theme, setTheme] = useState(localStorage.theme) + const [alertMessage, setAlertMessage] = useState(null) + + useEffect(() => { + document.documentElement.className = theme + localStorage.theme = theme + }, [theme]) const handleLogin = () => { - setView('home') + navigate('/') } const handleRegisterClick = () => { - setView('register') + navigate('/register') } const handleRegister = () => { - setView('login') + navigate('/login') } const handleLoginClick = () => { - setView('login') + navigate('/login') } const handleLogout = () => { - setView('login') + navigate('/login') } - return <> - {view === 'login' && } + const handleAlertAccept = () => setAlertMessage(null) - {view === 'register' && } + return + + : } /> - {view === 'home' && } - -} + : } /> -export default App + : } /> + + {alertMessage && } + +} diff --git a/staff/lucas-orts/ponies/app/views/Home.jsx b/staff/lucas-orts/ponies/app/views/Home.jsx deleted file mode 100644 index f3a93db48..000000000 --- a/staff/lucas-orts/ponies/app/views/Home.jsx +++ /dev/null @@ -1,52 +0,0 @@ -import Header from './home/Header' -import PostList from './home/PostList' -import Footer from './home/Footer' -import FollowingPostList from './home/FollowingPostList' -import FavsPostList from './home/FavsPostList' - -import { useState } from 'react' - -const Home = ({ onLogout }) => { - const [refreshStamp, setRefreshStamp] = useState(null) - const [view, setView] = useState('home') - - const handlePostCreated = () => { - setRefreshStamp(Date.now()) - } - - const handleFollowClick = () => { - setView('follows') - } - - const handleHomeClick = () => { - setView('home') - } - - const handleFavsClick = () => { - console.debug('Home -> handleFavsClick') - - setView('favs') - } - return <> -
- -
- {view === 'home' && } - - {view === 'follows' && } - - {view === 'favs' && } -
-