@stone-js/starters 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +101 -0
- package/basic-react-declarative/LICENSE +21 -0
- package/basic-react-declarative/README.md +39 -0
- package/basic-react-declarative/app/Application.tsx +89 -0
- package/basic-react-declarative/assets/css/index.css +26 -0
- package/basic-react-declarative/package.json +39 -0
- package/basic-react-declarative/public/logo.png +0 -0
- package/basic-react-declarative/tests/Application.spec.ts +96 -0
- package/basic-react-declarative/tests/__snapshots__/Application.spec.ts.snap +3 -0
- package/basic-react-declarative/tsconfig.json +33 -0
- package/basic-react-declarative/vitest.config.ts +24 -0
- package/basic-react-imperative/LICENSE +21 -0
- package/basic-react-imperative/README.md +39 -0
- package/basic-react-imperative/app/Application.tsx +89 -0
- package/basic-react-imperative/assets/css/index.css +26 -0
- package/basic-react-imperative/package.json +39 -0
- package/basic-react-imperative/public/logo.png +0 -0
- package/basic-react-imperative/tests/Application.spec.ts +80 -0
- package/basic-react-imperative/tests/__snapshots__/Application.spec.ts.snap +3 -0
- package/basic-react-imperative/tsconfig.json +33 -0
- package/basic-react-imperative/vitest.config.ts +24 -0
- package/basic-service-declarative/LICENSE +21 -0
- package/basic-service-declarative/README.md +39 -0
- package/basic-service-declarative/app/Application.ts +56 -0
- package/basic-service-declarative/package.json +34 -0
- package/basic-service-declarative/tests/Application.spec.ts +60 -0
- package/basic-service-declarative/tsconfig.json +25 -0
- package/basic-service-declarative/vitest.config.ts +24 -0
- package/basic-service-imperative/LICENSE +21 -0
- package/basic-service-imperative/README.md +39 -0
- package/basic-service-imperative/app/Application.ts +60 -0
- package/basic-service-imperative/package.json +34 -0
- package/basic-service-imperative/tests/Application.spec.ts +52 -0
- package/basic-service-imperative/tsconfig.json +25 -0
- package/basic-service-imperative/vitest.config.ts +24 -0
- package/continuum-showcase/README.md +44 -0
- package/continuum-showcase/app/env.d.ts +34 -0
- package/continuum-showcase/app/layouts/MainLayout.tsx +20 -0
- package/continuum-showcase/app/pages/BlogPostPage.tsx +62 -0
- package/continuum-showcase/app/pages/HomePage.tsx +58 -0
- package/continuum-showcase/package.json +25 -0
- package/continuum-showcase/stone.config.mjs +20 -0
- package/full-react-declarative/.env.example +1 -0
- package/full-react-declarative/.env.public.example +1 -0
- package/full-react-declarative/LICENSE +21 -0
- package/full-react-declarative/README.md +39 -0
- package/full-react-declarative/app/Application.ts +85 -0
- package/full-react-declarative/app/clients/AxiosClient.ts +136 -0
- package/full-react-declarative/app/clients/CommentClient.ts +61 -0
- package/full-react-declarative/app/clients/PostClient.ts +90 -0
- package/full-react-declarative/app/clients/SecurityClient.ts +66 -0
- package/full-react-declarative/app/clients/UserClient.ts +97 -0
- package/full-react-declarative/app/components/ChangePasswordForm/ChangePasswordForm.tsx +50 -0
- package/full-react-declarative/app/components/CommentForm/CommentForm.tsx +37 -0
- package/full-react-declarative/app/components/CommentItem/CommentItem.tsx +42 -0
- package/full-react-declarative/app/components/CommentWidget/CommentWidget.tsx +95 -0
- package/full-react-declarative/app/components/LoginForm/LoginForm.css +0 -0
- package/full-react-declarative/app/components/LoginForm/LoginForm.tsx +71 -0
- package/full-react-declarative/app/components/PostDetails/PostDetails.tsx +44 -0
- package/full-react-declarative/app/components/PostForm/PostForm.css +0 -0
- package/full-react-declarative/app/components/PostForm/PostForm.tsx +47 -0
- package/full-react-declarative/app/components/PostItem/PostItem.css +0 -0
- package/full-react-declarative/app/components/PostItem/PostItem.tsx +34 -0
- package/full-react-declarative/app/components/RegisterForm/RegisterForm.tsx +110 -0
- package/full-react-declarative/app/components/UserForm/UserForm.tsx +47 -0
- package/full-react-declarative/app/configurations/AppConfiguration.ts +17 -0
- package/full-react-declarative/app/error-pages/DefaultErrorPage/DefaultErrorPage.css +0 -0
- package/full-react-declarative/app/error-pages/DefaultErrorPage/DefaultErrorPage.tsx +52 -0
- package/full-react-declarative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.css +0 -0
- package/full-react-declarative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.tsx +53 -0
- package/full-react-declarative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.css +0 -0
- package/full-react-declarative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.tsx +54 -0
- package/full-react-declarative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.css +0 -0
- package/full-react-declarative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.tsx +53 -0
- package/full-react-declarative/app/errors/ForbiddenError.ts +11 -0
- package/full-react-declarative/app/errors/PostNotFoundError.ts +11 -0
- package/full-react-declarative/app/errors/UnauthorizedError.ts +11 -0
- package/full-react-declarative/app/errors/UserNotFoundError.ts +11 -0
- package/full-react-declarative/app/events/UserEvent.ts +18 -0
- package/full-react-declarative/app/layout/AppLayout/AppLayout.css +20 -0
- package/full-react-declarative/app/layout/AppLayout/AppLayout.tsx +101 -0
- package/full-react-declarative/app/layout/ErrorLayout/ErrorLayout.css +0 -0
- package/full-react-declarative/app/layout/ErrorLayout/ErrorLayout.tsx +41 -0
- package/full-react-declarative/app/layout/SecurityLayout/SecurityLayout.css +0 -0
- package/full-react-declarative/app/layout/SecurityLayout/SecurityLayout.tsx +39 -0
- package/full-react-declarative/app/middleware/AuthMiddleware.ts +85 -0
- package/full-react-declarative/app/models/Comment.ts +31 -0
- package/full-react-declarative/app/models/Post.ts +22 -0
- package/full-react-declarative/app/models/User.ts +62 -0
- package/full-react-declarative/app/pages/home/HomePage.tsx +44 -0
- package/full-react-declarative/app/pages/login/LoginPage.css +0 -0
- package/full-react-declarative/app/pages/login/LoginPage.tsx +73 -0
- package/full-react-declarative/app/pages/posts/CreatePostPage/CreatePostPage.css +0 -0
- package/full-react-declarative/app/pages/posts/CreatePostPage/CreatePostPage.tsx +67 -0
- package/full-react-declarative/app/pages/posts/PostPage/PostPage.tsx +60 -0
- package/full-react-declarative/app/pages/posts/ShowPostPage/ShowPostPage.tsx +83 -0
- package/full-react-declarative/app/pages/posts/UpdatePostPage/UpdatePostPage.tsx +77 -0
- package/full-react-declarative/app/pages/register/RegisterPage.tsx +68 -0
- package/full-react-declarative/app/pages/users/CreateUserPage.tsx +48 -0
- package/full-react-declarative/app/pages/users/ShowUserPage.tsx +62 -0
- package/full-react-declarative/app/pages/users/UpdateUserPage.tsx +57 -0
- package/full-react-declarative/app/pages/users/UserPage.tsx +57 -0
- package/full-react-declarative/app/providers/AppServiceProvider.ts +43 -0
- package/full-react-declarative/app/services/CommentService.ts +59 -0
- package/full-react-declarative/app/services/PostService.ts +108 -0
- package/full-react-declarative/app/services/SecurityService.ts +80 -0
- package/full-react-declarative/app/services/TokenService.ts +116 -0
- package/full-react-declarative/app/services/UserService.ts +126 -0
- package/full-react-declarative/app/utils.ts +17 -0
- package/full-react-declarative/assets/css/index.css +301 -0
- package/full-react-declarative/assets/img/logo.png +0 -0
- package/full-react-declarative/package.json +46 -0
- package/full-react-declarative/public/logo.png +0 -0
- package/full-react-declarative/public/vite.svg +1 -0
- package/full-react-declarative/stone.config.mjs +12 -0
- package/full-react-declarative/tsconfig.json +29 -0
- package/full-react-declarative/vitest.config.ts +24 -0
- package/full-react-imperative/.env.example +1 -0
- package/full-react-imperative/.env.public.example +1 -0
- package/full-react-imperative/LICENSE +21 -0
- package/full-react-imperative/README.md +39 -0
- package/full-react-imperative/app/Application.ts +79 -0
- package/full-react-imperative/app/clients/AxiosClient.ts +124 -0
- package/full-react-imperative/app/clients/CommentClient.ts +57 -0
- package/full-react-imperative/app/clients/PostClient.ts +86 -0
- package/full-react-imperative/app/clients/SecurityClient.ts +60 -0
- package/full-react-imperative/app/clients/UserClient.ts +93 -0
- package/full-react-imperative/app/clients/contracts/IAxiosClient.ts +97 -0
- package/full-react-imperative/app/clients/contracts/ICommentClient.ts +31 -0
- package/full-react-imperative/app/clients/contracts/IPostClient.ts +55 -0
- package/full-react-imperative/app/clients/contracts/ISecurityClient.ts +33 -0
- package/full-react-imperative/app/clients/contracts/IUserClient.ts +61 -0
- package/full-react-imperative/app/components/ChangePasswordForm/ChangePasswordForm.tsx +50 -0
- package/full-react-imperative/app/components/CommentForm/CommentForm.css +35 -0
- package/full-react-imperative/app/components/CommentForm/CommentForm.tsx +45 -0
- package/full-react-imperative/app/components/CommentItem/CommentItem.css +74 -0
- package/full-react-imperative/app/components/CommentItem/CommentItem.tsx +62 -0
- package/full-react-imperative/app/components/CommentWidget/CommentWidget.css +25 -0
- package/full-react-imperative/app/components/CommentWidget/CommentWidget.tsx +119 -0
- package/full-react-imperative/app/components/Dropdown/Dropdown.css +52 -0
- package/full-react-imperative/app/components/Dropdown/Dropdown.tsx +40 -0
- package/full-react-imperative/app/components/LayoutHeader/LayoutHeader.css +62 -0
- package/full-react-imperative/app/components/LayoutHeader/LayoutHeader.tsx +61 -0
- package/full-react-imperative/app/components/LayoutLeftMenu/LayoutLeftMenu.css +25 -0
- package/full-react-imperative/app/components/LayoutLeftMenu/LayoutLeftMenu.tsx +32 -0
- package/full-react-imperative/app/components/LoginForm/LoginForm.css +0 -0
- package/full-react-imperative/app/components/LoginForm/LoginForm.tsx +71 -0
- package/full-react-imperative/app/components/NotificationBadge/NotificationBadge.css +41 -0
- package/full-react-imperative/app/components/NotificationBadge/NotificationBadge.tsx +63 -0
- package/full-react-imperative/app/components/PostCard/PostCard.css +129 -0
- package/full-react-imperative/app/components/PostCard/PostCard.tsx +65 -0
- package/full-react-imperative/app/components/PostForm/PostForm.css +92 -0
- package/full-react-imperative/app/components/PostForm/PostForm.tsx +76 -0
- package/full-react-imperative/app/components/PostSkeleton/PostSkeleton.css +65 -0
- package/full-react-imperative/app/components/PostSkeleton/PostSkeleton.tsx +25 -0
- package/full-react-imperative/app/components/PostWidget/PostWidget.tsx +95 -0
- package/full-react-imperative/app/components/ProfileForm/ProfileForm.css +84 -0
- package/full-react-imperative/app/components/ProfileForm/ProfileForm.tsx +79 -0
- package/full-react-imperative/app/components/RegisterForm/RegisterForm.tsx +110 -0
- package/full-react-imperative/app/components/RightAsidePanel/RightAsidePanel.css +32 -0
- package/full-react-imperative/app/components/RightAsidePanel/RightAsidePanel.tsx +62 -0
- package/full-react-imperative/app/components/SettingsForm/SettingsForm.css +126 -0
- package/full-react-imperative/app/components/SettingsForm/SettingsForm.tsx +86 -0
- package/full-react-imperative/app/components/UserAvatar/UserAvatar.css +18 -0
- package/full-react-imperative/app/components/UserAvatar/UserAvatar.tsx +60 -0
- package/full-react-imperative/app/components/UserBadge/UserBadge.css +33 -0
- package/full-react-imperative/app/components/UserBadge/UserBadge.tsx +49 -0
- package/full-react-imperative/app/components/UserCard/UserCard.css +70 -0
- package/full-react-imperative/app/components/UserCard/UserCard.tsx +43 -0
- package/full-react-imperative/app/configurations/AppConfiguration.ts +19 -0
- package/full-react-imperative/app/error-pages/DefaultErrorPage/DefaultErrorPage.css +0 -0
- package/full-react-imperative/app/error-pages/DefaultErrorPage/DefaultErrorPage.tsx +41 -0
- package/full-react-imperative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.css +0 -0
- package/full-react-imperative/app/error-pages/ForbiddenErrorPage/ForbiddenErrorPage.tsx +42 -0
- package/full-react-imperative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.css +0 -0
- package/full-react-imperative/app/error-pages/NotFoundErrorPage/NotFoundErrorPage.tsx +49 -0
- package/full-react-imperative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.css +0 -0
- package/full-react-imperative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.tsx +42 -0
- package/full-react-imperative/app/errors/ForbiddenError.ts +11 -0
- package/full-react-imperative/app/errors/PostNotFoundError.ts +11 -0
- package/full-react-imperative/app/errors/UnauthorizedError.ts +11 -0
- package/full-react-imperative/app/errors/UserNotFoundError.ts +11 -0
- package/full-react-imperative/app/events/UserEvent.ts +18 -0
- package/full-react-imperative/app/layout/AppLayout/AppLayout.css +106 -0
- package/full-react-imperative/app/layout/AppLayout/AppLayout.tsx +48 -0
- package/full-react-imperative/app/layout/ErrorLayout/ErrorLayout.css +0 -0
- package/full-react-imperative/app/layout/ErrorLayout/ErrorLayout.tsx +45 -0
- package/full-react-imperative/app/layout/SecurityLayout/SecurityLayout.css +0 -0
- package/full-react-imperative/app/layout/SecurityLayout/SecurityLayout.tsx +43 -0
- package/full-react-imperative/app/layout/SettingsLayout/SettingsLayout.css +99 -0
- package/full-react-imperative/app/layout/SettingsLayout/SettingsLayout.tsx +44 -0
- package/full-react-imperative/app/middleware/AuthMiddleware.ts +56 -0
- package/full-react-imperative/app/models/Comment.ts +35 -0
- package/full-react-imperative/app/models/Post.ts +27 -0
- package/full-react-imperative/app/models/User.ts +68 -0
- package/full-react-imperative/app/pages/Settings/SettingsPage.tsx +23 -0
- package/full-react-imperative/app/pages/home/HomePage.tsx +58 -0
- package/full-react-imperative/app/pages/login/LoginPage.css +0 -0
- package/full-react-imperative/app/pages/login/LoginPage.tsx +65 -0
- package/full-react-imperative/app/pages/posts/ShowPostPage/ShowPostPage.tsx +64 -0
- package/full-react-imperative/app/pages/posts/UpdatePostPage/UpdatePostPage.tsx +56 -0
- package/full-react-imperative/app/pages/register/RegisterPage.tsx +71 -0
- package/full-react-imperative/app/pages/users/ShowUserPage/ShowUserPage.css +64 -0
- package/full-react-imperative/app/pages/users/ShowUserPage/ShowUserPage.tsx +104 -0
- package/full-react-imperative/app/pages/users/UpdateUserPage/UpdateUserPage.css +0 -0
- package/full-react-imperative/app/pages/users/UpdateUserPage/UpdateUserPage.tsx +43 -0
- package/full-react-imperative/app/pages/users/UserPage/UserPage.css +31 -0
- package/full-react-imperative/app/pages/users/UserPage/UserPage.tsx +59 -0
- package/full-react-imperative/app/pages/utils.ts +67 -0
- package/full-react-imperative/app/providers/AppServiceProvider.ts +40 -0
- package/full-react-imperative/app/services/CommentService.ts +53 -0
- package/full-react-imperative/app/services/PostService.ts +102 -0
- package/full-react-imperative/app/services/SecurityService.ts +72 -0
- package/full-react-imperative/app/services/TokenService.ts +108 -0
- package/full-react-imperative/app/services/UserService.ts +115 -0
- package/full-react-imperative/app/services/contracts/ICommentService.ts +30 -0
- package/full-react-imperative/app/services/contracts/IPostService.ts +65 -0
- package/full-react-imperative/app/services/contracts/ISecurityService.ts +39 -0
- package/full-react-imperative/app/services/contracts/ITokenService.ts +44 -0
- package/full-react-imperative/app/services/contracts/IUserService.ts +70 -0
- package/full-react-imperative/app/utils.ts +31 -0
- package/full-react-imperative/assets/css/index.css +301 -0
- package/full-react-imperative/assets/img/logo.png +0 -0
- package/full-react-imperative/package.json +48 -0
- package/full-react-imperative/public/logo.png +0 -0
- package/full-react-imperative/public/vite.svg +1 -0
- package/full-react-imperative/stone.config.mjs +12 -0
- package/full-react-imperative/tsconfig.json +29 -0
- package/full-react-imperative/vitest.config.ts +24 -0
- package/full-service-declarative/.env.example +2 -0
- package/full-service-declarative/LICENSE +21 -0
- package/full-service-declarative/README.md +65 -0
- package/full-service-declarative/app/Application.ts +327 -0
- package/full-service-declarative/app/commands/ListSessionsCommand.ts +70 -0
- package/full-service-declarative/app/commands/ListUsersCommand.ts +56 -0
- package/full-service-declarative/app/configurations/AppConfiguration.ts +52 -0
- package/full-service-declarative/app/configurations/UserLiveConfiguration.ts +28 -0
- package/full-service-declarative/app/database/DatabaseClient.ts +43 -0
- package/full-service-declarative/app/database/schema.ts +43 -0
- package/full-service-declarative/app/error-handlers/SecurityErrorHandler.ts +61 -0
- package/full-service-declarative/app/errors/CredentialsError.ts +12 -0
- package/full-service-declarative/app/events/UserEvent.ts +17 -0
- package/full-service-declarative/app/handlers/CommentEventHandler.ts +103 -0
- package/full-service-declarative/app/handlers/PostEventHandler.ts +104 -0
- package/full-service-declarative/app/handlers/SecurityEventHandler.ts +108 -0
- package/full-service-declarative/app/handlers/UserEventHandler.ts +159 -0
- package/full-service-declarative/app/listeners/UserEventListener.ts +35 -0
- package/full-service-declarative/app/middleware/AuthMiddleware.ts +54 -0
- package/full-service-declarative/app/models/Comment.ts +38 -0
- package/full-service-declarative/app/models/Post.ts +50 -0
- package/full-service-declarative/app/models/Session.ts +14 -0
- package/full-service-declarative/app/models/User.ts +77 -0
- package/full-service-declarative/app/providers/DrizzleServiceProvider.ts +59 -0
- package/full-service-declarative/app/repositories/CommentRepository.ts +155 -0
- package/full-service-declarative/app/repositories/PostRepository.ts +138 -0
- package/full-service-declarative/app/repositories/SessionRepository.ts +123 -0
- package/full-service-declarative/app/repositories/UserRepository.ts +99 -0
- package/full-service-declarative/app/services/CommentService.ts +112 -0
- package/full-service-declarative/app/services/PostService.ts +100 -0
- package/full-service-declarative/app/services/SecurityService.ts +232 -0
- package/full-service-declarative/app/services/SessionService.ts +130 -0
- package/full-service-declarative/app/services/UserService.ts +110 -0
- package/full-service-declarative/app/subscribers/UserEventSubscriber.ts +38 -0
- package/full-service-declarative/drizzle.config.ts +13 -0
- package/full-service-declarative/package.json +48 -0
- package/full-service-declarative/stone.config.mjs +12 -0
- package/full-service-declarative/tsconfig.json +25 -0
- package/full-service-declarative/vitest.config.ts +24 -0
- package/full-service-imperative/.env.example +2 -0
- package/full-service-imperative/LICENSE +21 -0
- package/full-service-imperative/README.md +65 -0
- package/full-service-imperative/app/Application.ts +317 -0
- package/full-service-imperative/app/commands/ListSessionsCommand.ts +54 -0
- package/full-service-imperative/app/commands/ListUsersCommand.ts +42 -0
- package/full-service-imperative/app/configurations/AppConfiguration.ts +44 -0
- package/full-service-imperative/app/configurations/UserLiveConfiguration.ts +26 -0
- package/full-service-imperative/app/database/DatabaseClient.ts +39 -0
- package/full-service-imperative/app/database/schema.ts +43 -0
- package/full-service-imperative/app/error-handlers/SecurityErrorHandler.ts +58 -0
- package/full-service-imperative/app/errors/CredentialsError.ts +12 -0
- package/full-service-imperative/app/events/UserEvent.ts +17 -0
- package/full-service-imperative/app/handlers/CommentEventHandler.ts +99 -0
- package/full-service-imperative/app/handlers/PostEventHandler.ts +99 -0
- package/full-service-imperative/app/handlers/SecurityEventHandler.ts +83 -0
- package/full-service-imperative/app/handlers/UserEventHandler.ts +132 -0
- package/full-service-imperative/app/listeners/UserEventListener.ts +23 -0
- package/full-service-imperative/app/middleware/AuthMiddleware.ts +44 -0
- package/full-service-imperative/app/models/Comment.ts +38 -0
- package/full-service-imperative/app/models/Post.ts +50 -0
- package/full-service-imperative/app/models/Session.ts +14 -0
- package/full-service-imperative/app/models/User.ts +77 -0
- package/full-service-imperative/app/providers/DrizzleServiceProvider.ts +56 -0
- package/full-service-imperative/app/repositories/CommentRepository.ts +148 -0
- package/full-service-imperative/app/repositories/PostRepository.ts +130 -0
- package/full-service-imperative/app/repositories/SessionRepository.ts +115 -0
- package/full-service-imperative/app/repositories/UserRepository.ts +91 -0
- package/full-service-imperative/app/repositories/contracts/ICommentRepository.ts +72 -0
- package/full-service-imperative/app/repositories/contracts/IPostRepository.ts +63 -0
- package/full-service-imperative/app/repositories/contracts/ISessionRepository.ts +65 -0
- package/full-service-imperative/app/repositories/contracts/IUserRepository.ts +55 -0
- package/full-service-imperative/app/services/CommentService.ts +109 -0
- package/full-service-imperative/app/services/PostService.ts +97 -0
- package/full-service-imperative/app/services/SecurityService.ts +224 -0
- package/full-service-imperative/app/services/SessionService.ts +124 -0
- package/full-service-imperative/app/services/UserService.ts +105 -0
- package/full-service-imperative/app/services/contracts/ICommentService.ts +62 -0
- package/full-service-imperative/app/services/contracts/IPostService.ts +53 -0
- package/full-service-imperative/app/services/contracts/ISecurityService.ts +97 -0
- package/full-service-imperative/app/services/contracts/ISessionService.ts +73 -0
- package/full-service-imperative/app/services/contracts/IUserService.ts +57 -0
- package/full-service-imperative/app/subscribers/UserEventSubscriber.ts +28 -0
- package/full-service-imperative/drizzle.config.ts +13 -0
- package/full-service-imperative/package.json +48 -0
- package/full-service-imperative/stone.config.mjs +12 -0
- package/full-service-imperative/tsconfig.json +25 -0
- package/full-service-imperative/vitest.config.ts +24 -0
- package/package.json +225 -0
- package/standard-react-declarative/LICENSE +21 -0
- package/standard-react-declarative/README.md +39 -0
- package/standard-react-declarative/app/Application.ts +45 -0
- package/standard-react-declarative/app/pages/welcome/WelcomePage.tsx +57 -0
- package/standard-react-declarative/app/services/WelcomeService.ts +38 -0
- package/standard-react-declarative/assets/css/index.css +26 -0
- package/standard-react-declarative/package.json +42 -0
- package/standard-react-declarative/tsconfig.json +33 -0
- package/standard-react-declarative/vitest.config.ts +24 -0
- package/standard-react-imperative/LICENSE +21 -0
- package/standard-react-imperative/README.md +39 -0
- package/standard-react-imperative/app/Application.ts +41 -0
- package/standard-react-imperative/app/pages/welcome/WelcomePage.tsx +50 -0
- package/standard-react-imperative/app/services/WelcomeService.ts +38 -0
- package/standard-react-imperative/assets/css/index.css +26 -0
- package/standard-react-imperative/package.json +42 -0
- package/standard-react-imperative/tsconfig.json +33 -0
- package/standard-react-imperative/vitest.config.ts +24 -0
- package/standard-service-declarative/LICENSE +21 -0
- package/standard-service-declarative/README.md +39 -0
- package/standard-service-declarative/app/Application.ts +39 -0
- package/standard-service-declarative/app/handlers/WelcomeEventHandler.ts +45 -0
- package/standard-service-declarative/app/services/WelcomeService.ts +38 -0
- package/standard-service-declarative/package.json +36 -0
- package/standard-service-declarative/tsconfig.json +25 -0
- package/standard-service-declarative/vitest.config.ts +24 -0
- package/standard-service-imperative/LICENSE +21 -0
- package/standard-service-imperative/README.md +39 -0
- package/standard-service-imperative/app/Application.ts +11 -0
- package/standard-service-imperative/app/handlers/welcomeEventHandler.ts +31 -0
- package/standard-service-imperative/app/services/welcomeService.ts +38 -0
- package/standard-service-imperative/package.json +35 -0
- package/standard-service-imperative/tsconfig.json +25 -0
- package/standard-service-imperative/vitest.config.ts +24 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { UserService } from '../services/UserService'
|
|
2
|
+
import { SecurityService } from '../services/SecurityService'
|
|
3
|
+
import { IBlueprint, IMiddleware, Middleware, NextMiddleware } from '@stone-js/core'
|
|
4
|
+
import { ISnapshot, isServer, ReactIncomingEvent, ReactOutgoingResponse, reactRedirectResponse } from '@stone-js/use-react'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* AuthMiddleware Options
|
|
8
|
+
*/
|
|
9
|
+
export interface AuthMiddlewareOptions {
|
|
10
|
+
snapshot: ISnapshot
|
|
11
|
+
blueprint: IBlueprint
|
|
12
|
+
userService: UserService
|
|
13
|
+
securityService: SecurityService
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Set current user middleware
|
|
18
|
+
*/
|
|
19
|
+
@Middleware({
|
|
20
|
+
global: true,
|
|
21
|
+
params: [['/login', '/register']]
|
|
22
|
+
})
|
|
23
|
+
export class AuthMiddleware implements IMiddleware<ReactIncomingEvent, ReactOutgoingResponse> {
|
|
24
|
+
private readonly snapshot: ISnapshot
|
|
25
|
+
private readonly blueprint: IBlueprint
|
|
26
|
+
private readonly userService: UserService
|
|
27
|
+
private readonly securityService: SecurityService
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Create a new instance of AuthMiddleware
|
|
31
|
+
*
|
|
32
|
+
* @param userService
|
|
33
|
+
*/
|
|
34
|
+
constructor ({ blueprint, snapshot, userService, securityService }: AuthMiddlewareOptions) {
|
|
35
|
+
this.snapshot = snapshot
|
|
36
|
+
this.blueprint = blueprint
|
|
37
|
+
this.userService = userService
|
|
38
|
+
this.securityService = securityService
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Handle the incoming event
|
|
43
|
+
*
|
|
44
|
+
* @param event - The incoming event
|
|
45
|
+
* @param next - The next middleware
|
|
46
|
+
* @returns The response
|
|
47
|
+
*/
|
|
48
|
+
async handle (
|
|
49
|
+
event: ReactIncomingEvent,
|
|
50
|
+
next: NextMiddleware<ReactIncomingEvent, ReactOutgoingResponse>,
|
|
51
|
+
excludes: string[] = []
|
|
52
|
+
): Promise<ReactOutgoingResponse> {
|
|
53
|
+
if (!excludes.includes(event.pathname)) {
|
|
54
|
+
if (!this.securityService.isAuthenticated()) {
|
|
55
|
+
this.blueprint.set('app.requestedUrl', event.pathname)
|
|
56
|
+
return await reactRedirectResponse({ url: '/login' })
|
|
57
|
+
}
|
|
58
|
+
await this.resolveCurrentUser(event)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return await next(event)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Resolve the current user and store it in the snapshot.
|
|
66
|
+
*
|
|
67
|
+
* This method uses the event fingerprint to store the user in the snapshot,
|
|
68
|
+
* ensuring that the snapshot is valid per request. If the user is already
|
|
69
|
+
* stored in the snapshot, it is retrieved from there; otherwise, it is
|
|
70
|
+
* fetched from the server.
|
|
71
|
+
*
|
|
72
|
+
* @param event - The incoming event
|
|
73
|
+
*/
|
|
74
|
+
private async resolveCurrentUser (event: ReactIncomingEvent): Promise<void> {
|
|
75
|
+
if (isServer()) {
|
|
76
|
+
const user = await this.userService.current()
|
|
77
|
+
event.setUserResolver(() => user)
|
|
78
|
+
this.snapshot.set(`${event.fingerprint()}.user`, user)
|
|
79
|
+
} else {
|
|
80
|
+
let user = this.snapshot.get(`${event.fingerprint()}.user`)
|
|
81
|
+
user ??= await this.userService.current(true)
|
|
82
|
+
event.setUserResolver(() => user)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { User } from './User'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Comment Interface
|
|
5
|
+
*/
|
|
6
|
+
export interface Comment {
|
|
7
|
+
id: number
|
|
8
|
+
author: User
|
|
9
|
+
content: string
|
|
10
|
+
authorId: number
|
|
11
|
+
postId: number
|
|
12
|
+
createdAt: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* New Comment Interface
|
|
17
|
+
*/
|
|
18
|
+
export interface CommentInput {
|
|
19
|
+
id: number
|
|
20
|
+
content: string
|
|
21
|
+
postId: number
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Comment View Interface
|
|
26
|
+
*/
|
|
27
|
+
export interface CommentView extends CommentInput {
|
|
28
|
+
author: User
|
|
29
|
+
createdAt: number
|
|
30
|
+
status?: 'idle' | 'saving' | 'error'
|
|
31
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { User } from './User'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Post Interface
|
|
5
|
+
*/
|
|
6
|
+
export interface Post {
|
|
7
|
+
id: number
|
|
8
|
+
author: User
|
|
9
|
+
title: string
|
|
10
|
+
content: string
|
|
11
|
+
authorId: number
|
|
12
|
+
createdAt: number
|
|
13
|
+
updatedAt: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* New Post Interface
|
|
18
|
+
*/
|
|
19
|
+
export interface PostInput {
|
|
20
|
+
title: string
|
|
21
|
+
content: string
|
|
22
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Interface
|
|
3
|
+
*/
|
|
4
|
+
export interface User {
|
|
5
|
+
id: number
|
|
6
|
+
name: string
|
|
7
|
+
email: string
|
|
8
|
+
avatar: string
|
|
9
|
+
createdAt: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* New User Interface
|
|
14
|
+
*/
|
|
15
|
+
export interface UserInput {
|
|
16
|
+
name: string
|
|
17
|
+
email: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* User Login Interface
|
|
22
|
+
*/
|
|
23
|
+
export interface UserLogin {
|
|
24
|
+
email: string
|
|
25
|
+
password: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* User Register Interface
|
|
30
|
+
*/
|
|
31
|
+
export interface UserRegister {
|
|
32
|
+
name: string
|
|
33
|
+
email: string
|
|
34
|
+
password: string
|
|
35
|
+
confirmPassword: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* User Register Errors Type
|
|
40
|
+
*/
|
|
41
|
+
export type UserRegisterErrors = Record<string, string>
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* User Change Password Interface
|
|
45
|
+
*/
|
|
46
|
+
export interface UserChangePassword {
|
|
47
|
+
password: string
|
|
48
|
+
newPassword: string
|
|
49
|
+
confirmPassword: string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* User Token Interface
|
|
54
|
+
*/
|
|
55
|
+
export interface UserToken {
|
|
56
|
+
scope: string
|
|
57
|
+
stage: string
|
|
58
|
+
createdAt: number
|
|
59
|
+
expiresIn: number
|
|
60
|
+
tokenType: string
|
|
61
|
+
accessToken: string
|
|
62
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { IPage, Page, ReactIncomingEvent, StoneLink, HeadContext } from '@stone-js/use-react'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Home Page component.
|
|
6
|
+
*/
|
|
7
|
+
@Page('/')
|
|
8
|
+
export class HomePage implements IPage<ReactIncomingEvent> {
|
|
9
|
+
head (): HeadContext {
|
|
10
|
+
return {
|
|
11
|
+
title: 'Home',
|
|
12
|
+
description: 'Welcome to the Stone.js Blog Dashboard'
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Render the component.
|
|
18
|
+
*
|
|
19
|
+
* @returns The rendered component.
|
|
20
|
+
*/
|
|
21
|
+
render (): JSX.Element {
|
|
22
|
+
return (
|
|
23
|
+
<div>
|
|
24
|
+
<h1>Stone.js Blog Dashboard</h1>
|
|
25
|
+
<p>Welcome to the Stone.js Blog Dashboard.</p>
|
|
26
|
+
<div>
|
|
27
|
+
<h2>Posts</h2>
|
|
28
|
+
<p>View the latest posts from the Stone.js Blog.</p>
|
|
29
|
+
<StoneLink to='/posts'>View Posts</StoneLink>
|
|
30
|
+
</div>
|
|
31
|
+
<div>
|
|
32
|
+
<h2>Users</h2>
|
|
33
|
+
<p>View the latest users from the Stone.js Blog.</p>
|
|
34
|
+
<StoneLink to='/users'>View Users</StoneLink>
|
|
35
|
+
</div>
|
|
36
|
+
<div>
|
|
37
|
+
<h2>Manage</h2>
|
|
38
|
+
<p>Manage your profile</p>
|
|
39
|
+
<StoneLink to='/manage'>Manage</StoneLink>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import './LoginPage.css'
|
|
2
|
+
import { IBlueprint } from '@stone-js/core'
|
|
3
|
+
import { UserLogin } from '../../models/User'
|
|
4
|
+
import { Dispatch, JSX, SetStateAction, useState } from 'react'
|
|
5
|
+
import { LoginForm } from '../../components/LoginForm/LoginForm'
|
|
6
|
+
import { SecurityService } from '../../services/SecurityService'
|
|
7
|
+
import { IPage, IRouter, Page, ReactIncomingEvent } from '@stone-js/use-react'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Login Page options.
|
|
11
|
+
*/
|
|
12
|
+
interface LoginPageOptions {
|
|
13
|
+
router: IRouter
|
|
14
|
+
blueprint: IBlueprint
|
|
15
|
+
securityService: SecurityService
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Login Page component.
|
|
20
|
+
*/
|
|
21
|
+
@Page('/login', { layout: 'security' })
|
|
22
|
+
export class LoginPage implements IPage<ReactIncomingEvent> {
|
|
23
|
+
private readonly router: IRouter
|
|
24
|
+
private readonly blueprint: IBlueprint
|
|
25
|
+
private readonly securityService: SecurityService
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create a new Login Page component.
|
|
29
|
+
*
|
|
30
|
+
* @param options - The options to create the Login Page component.
|
|
31
|
+
*/
|
|
32
|
+
constructor ({ router, blueprint, securityService }: LoginPageOptions) {
|
|
33
|
+
this.router = router
|
|
34
|
+
this.blueprint = blueprint
|
|
35
|
+
this.securityService = securityService
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Render the component.
|
|
40
|
+
*
|
|
41
|
+
* @param options - The options for rendering the component.
|
|
42
|
+
* @returns The rendered component.
|
|
43
|
+
*/
|
|
44
|
+
render (): JSX.Element {
|
|
45
|
+
const [error, setError] = useState<boolean>(false)
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div>
|
|
49
|
+
<LoginForm
|
|
50
|
+
error={error}
|
|
51
|
+
onSubmit={async (user: UserLogin) => await this.login(user, setError)}
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Login the user.
|
|
59
|
+
*
|
|
60
|
+
* @param user - The user to login.
|
|
61
|
+
*/
|
|
62
|
+
private async login (
|
|
63
|
+
user: UserLogin,
|
|
64
|
+
setError: Dispatch<SetStateAction<boolean>>
|
|
65
|
+
): Promise<void> {
|
|
66
|
+
try {
|
|
67
|
+
await this.securityService.login(user)
|
|
68
|
+
this.router.navigate(this.blueprint.get('app.requestedUrl', '/'), true)
|
|
69
|
+
} catch (_: any) {
|
|
70
|
+
setError(true)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import './CreatePostPage.css'
|
|
2
|
+
import { JSX } from 'react'
|
|
3
|
+
import { ILogger } from '@stone-js/core'
|
|
4
|
+
import { PostInput } from '../../../models/Post'
|
|
5
|
+
import { PostService } from '../../../services/PostService'
|
|
6
|
+
import { PostForm } from '../../../components/PostForm/PostForm'
|
|
7
|
+
import { IPage, IRouter, Page, ReactIncomingEvent } from '@stone-js/use-react'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Create Post Page options.
|
|
11
|
+
*/
|
|
12
|
+
export interface CreatePostPageOptions {
|
|
13
|
+
router: IRouter
|
|
14
|
+
logger: ILogger
|
|
15
|
+
postService: PostService
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create Post Page component.
|
|
20
|
+
*/
|
|
21
|
+
@Page('/posts/create')
|
|
22
|
+
export class CreatePostPage implements IPage<ReactIncomingEvent> {
|
|
23
|
+
private readonly router: IRouter
|
|
24
|
+
private readonly logger: ILogger
|
|
25
|
+
private readonly postService: PostService
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create a new Post Page component.
|
|
29
|
+
*
|
|
30
|
+
* @param options - The options to create the Post Page component.
|
|
31
|
+
*/
|
|
32
|
+
constructor ({ router, logger, postService }: CreatePostPageOptions) {
|
|
33
|
+
this.router = router
|
|
34
|
+
this.logger = logger
|
|
35
|
+
this.postService = postService
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Render the component.
|
|
40
|
+
*
|
|
41
|
+
* @returns The rendered component.
|
|
42
|
+
*/
|
|
43
|
+
render (): JSX.Element {
|
|
44
|
+
return (
|
|
45
|
+
<>
|
|
46
|
+
<h1>New Post</h1>
|
|
47
|
+
<PostForm onSubmit={this.createPost.bind(this)} />
|
|
48
|
+
</>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Create the post.
|
|
54
|
+
*
|
|
55
|
+
* @param post - The post to save.
|
|
56
|
+
*/
|
|
57
|
+
private async createPost (postInput: PostInput): Promise<void> {
|
|
58
|
+
try {
|
|
59
|
+
const post = await this.postService.create(postInput)
|
|
60
|
+
this.router.navigate(`/posts/${post.id}`)
|
|
61
|
+
} catch (error: any) {
|
|
62
|
+
console.error(error)
|
|
63
|
+
window.alert('Error creating the post')
|
|
64
|
+
this.logger.error(error.message, { error })
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { Post } from '../../../models/Post'
|
|
3
|
+
import { PostService } from '../../../services/PostService'
|
|
4
|
+
import { PostItem } from '../../../components/PostItem/PostItem'
|
|
5
|
+
import { IPage, Page, PageRenderContext, ReactIncomingEvent, StoneLink } from '@stone-js/use-react'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Post Page options.
|
|
9
|
+
*/
|
|
10
|
+
export interface PostPageOptions {
|
|
11
|
+
postService: PostService
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* List Post Page component.
|
|
16
|
+
*/
|
|
17
|
+
@Page('/posts')
|
|
18
|
+
export class PostPage implements IPage<ReactIncomingEvent> {
|
|
19
|
+
private readonly postService: PostService
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Create a new List Post Page component.
|
|
23
|
+
*
|
|
24
|
+
* @param options - The options to create the List Post Page component.
|
|
25
|
+
*/
|
|
26
|
+
constructor ({ postService }: PostPageOptions) {
|
|
27
|
+
this.postService = postService
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Handle the incoming event.
|
|
32
|
+
*
|
|
33
|
+
* @param event - The incoming event.
|
|
34
|
+
* @returns List of posts.
|
|
35
|
+
*/
|
|
36
|
+
async handle (event: ReactIncomingEvent): Promise<Post[]> {
|
|
37
|
+
return await this.postService.list(event.get<number>('limit', 10))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Render the component.
|
|
42
|
+
*
|
|
43
|
+
* @param options - The options for rendering the component.
|
|
44
|
+
* @returns The rendered component.
|
|
45
|
+
*/
|
|
46
|
+
render ({ data: posts }: PageRenderContext<Post[]>): JSX.Element {
|
|
47
|
+
return (
|
|
48
|
+
<>
|
|
49
|
+
<h1>
|
|
50
|
+
<span>Posts</span>
|
|
51
|
+
<StoneLink to='/posts/create'>New Post</StoneLink>
|
|
52
|
+
</h1>
|
|
53
|
+
<div>
|
|
54
|
+
{posts?.length === 0 && <p>No posts found.</p>}
|
|
55
|
+
{posts?.map(post => <PostItem key={post.id} post={post} />)}
|
|
56
|
+
</div>
|
|
57
|
+
</>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { Post } from '../../../models/Post'
|
|
3
|
+
import { User } from '../../../models/User'
|
|
4
|
+
import { ILogger, isNotEmpty } from '@stone-js/core'
|
|
5
|
+
import { PostService } from '../../../services/PostService'
|
|
6
|
+
import { CommentService } from '../../../services/CommentService'
|
|
7
|
+
import { PostDetails } from '../../../components/PostDetails/PostDetails'
|
|
8
|
+
import { IPage, IRouter, Page, PageRenderContext, ReactIncomingEvent } from '@stone-js/use-react'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Show Post Page options.
|
|
12
|
+
*/
|
|
13
|
+
export interface ShowPostPageOptions {
|
|
14
|
+
router: IRouter
|
|
15
|
+
logger: ILogger
|
|
16
|
+
postService: PostService
|
|
17
|
+
commentService: CommentService
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Show Post Page component.
|
|
22
|
+
*/
|
|
23
|
+
@Page('/posts/:post@id(\\d+)', { bindings: { post: 'postService@findBy' } })
|
|
24
|
+
export class ShowPostPage implements IPage<ReactIncomingEvent> {
|
|
25
|
+
private readonly router: IRouter
|
|
26
|
+
private readonly logger: ILogger
|
|
27
|
+
private readonly postService: PostService
|
|
28
|
+
private readonly commentService: CommentService
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a new Post Page component.
|
|
32
|
+
*
|
|
33
|
+
* @param options - The options to create the Post Page component.
|
|
34
|
+
*/
|
|
35
|
+
constructor ({ router, logger, postService, commentService }: ShowPostPageOptions) {
|
|
36
|
+
this.router = router
|
|
37
|
+
this.logger = logger
|
|
38
|
+
this.postService = postService
|
|
39
|
+
this.commentService = commentService
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Render the component.
|
|
44
|
+
*
|
|
45
|
+
* @param options - The options for rendering the component.
|
|
46
|
+
* @returns The rendered component.
|
|
47
|
+
*/
|
|
48
|
+
render ({ event }: PageRenderContext<Post>): JSX.Element {
|
|
49
|
+
const post = event.get<Post>('post')
|
|
50
|
+
const user = event.getUser<User>() ?? {} as unknown as User
|
|
51
|
+
|
|
52
|
+
// Render the component
|
|
53
|
+
if (isNotEmpty<Post>(post)) {
|
|
54
|
+
return (
|
|
55
|
+
<PostDetails
|
|
56
|
+
user={user}
|
|
57
|
+
post={post}
|
|
58
|
+
onDelete={this.deletePost.bind(this)}
|
|
59
|
+
commentService={this.commentService}
|
|
60
|
+
/>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return <article><h1>Post not found</h1></article>
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Delete the post.
|
|
69
|
+
*
|
|
70
|
+
* @param post - The post to delete.
|
|
71
|
+
*/
|
|
72
|
+
private async deletePost (post: Post): Promise<void> {
|
|
73
|
+
if (window.confirm('Are you sure you want to delete this post?')) {
|
|
74
|
+
try {
|
|
75
|
+
await this.postService.delete(post.id)
|
|
76
|
+
this.router.navigate('/posts')
|
|
77
|
+
} catch (error: any) {
|
|
78
|
+
window.alert('Error deleting the post')
|
|
79
|
+
this.logger.error(error.message, { error })
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { ILogger, isNotEmpty } from '@stone-js/core'
|
|
3
|
+
import { Post, PostInput } from '../../../models/Post'
|
|
4
|
+
import { PostService } from '../../../services/PostService'
|
|
5
|
+
import { PostForm } from '../../../components/PostForm/PostForm'
|
|
6
|
+
import { IPage, Page, ReactIncomingEvent, PageRenderContext, StoneLink } from '@stone-js/use-react'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Update Post Page options.
|
|
10
|
+
*/
|
|
11
|
+
export interface UpdatePostPageOptions {
|
|
12
|
+
logger: ILogger
|
|
13
|
+
postService: PostService
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Update Post Page component.
|
|
18
|
+
*/
|
|
19
|
+
@Page('/posts/:post@id(\\d+)/edit', { bindings: { post: 'postService@findBy' } })
|
|
20
|
+
export class UpdatePostPage implements IPage<ReactIncomingEvent> {
|
|
21
|
+
private readonly logger: ILogger
|
|
22
|
+
private readonly postService: PostService
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create a new Post Page component.
|
|
26
|
+
*
|
|
27
|
+
* @param options - The options to create the Post Page component.
|
|
28
|
+
*/
|
|
29
|
+
constructor ({ logger, postService }: UpdatePostPageOptions) {
|
|
30
|
+
this.logger = logger
|
|
31
|
+
this.postService = postService
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Render the component.
|
|
36
|
+
*
|
|
37
|
+
* @param options - The options for rendering the component.
|
|
38
|
+
* @returns The rendered component.
|
|
39
|
+
*/
|
|
40
|
+
render ({ event }: PageRenderContext<Post>): JSX.Element {
|
|
41
|
+
const post = event.get<Post>('post')
|
|
42
|
+
|
|
43
|
+
if (isNotEmpty<Post>(post)) {
|
|
44
|
+
return (
|
|
45
|
+
<>
|
|
46
|
+
<h1>{post.title}</h1>
|
|
47
|
+
<PostForm
|
|
48
|
+
post={post}
|
|
49
|
+
onSubmit={async (postInput) => await this.updatePost(post.id, postInput)}
|
|
50
|
+
/>
|
|
51
|
+
<StoneLink to={`/posts/${post.id}`}>Back</StoneLink>
|
|
52
|
+
</>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<article>
|
|
58
|
+
<h1>Post not found</h1>
|
|
59
|
+
</article>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Update the post.
|
|
65
|
+
*
|
|
66
|
+
* @param post - The post to update.
|
|
67
|
+
*/
|
|
68
|
+
private async updatePost (id: number, post: PostInput): Promise<void> {
|
|
69
|
+
try {
|
|
70
|
+
await this.postService.update(id, post)
|
|
71
|
+
window.alert('Post updated successfully')
|
|
72
|
+
} catch (error: any) {
|
|
73
|
+
window.alert('Error updating the post')
|
|
74
|
+
this.logger.error(error.message, { error })
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Dispatch, JSX, SetStateAction, useState } from 'react'
|
|
2
|
+
import { SecurityService } from '../../services/SecurityService'
|
|
3
|
+
import { UserRegister, UserRegisterErrors } from '../../models/User'
|
|
4
|
+
import { IPage, Page, ReactIncomingEvent } from '@stone-js/use-react'
|
|
5
|
+
import { RegisterForm } from '../../components/RegisterForm/RegisterForm'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Register Page options.
|
|
9
|
+
*/
|
|
10
|
+
interface RegisterPageOptions {
|
|
11
|
+
securityService: SecurityService
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Register Page component.
|
|
16
|
+
*/
|
|
17
|
+
@Page('/register', { layout: 'security' })
|
|
18
|
+
export class RegisterPage implements IPage<ReactIncomingEvent> {
|
|
19
|
+
private readonly securityService: SecurityService
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Create a new Register Page component.
|
|
23
|
+
*
|
|
24
|
+
* @param options - The options to create the Register Page component.
|
|
25
|
+
*/
|
|
26
|
+
constructor ({ securityService }: RegisterPageOptions) {
|
|
27
|
+
this.securityService = securityService
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Render the component.
|
|
32
|
+
*
|
|
33
|
+
* @param options - The options for rendering the component.
|
|
34
|
+
* @returns The rendered component.
|
|
35
|
+
*/
|
|
36
|
+
render (): JSX.Element {
|
|
37
|
+
const [done, setDone] = useState<boolean>(false)
|
|
38
|
+
const [error, setError] = useState<UserRegisterErrors>({})
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div>
|
|
42
|
+
<RegisterForm
|
|
43
|
+
done={done}
|
|
44
|
+
error={error}
|
|
45
|
+
onSubmit={async (user: UserRegister) => await this.register(user, setDone, setError)}
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Register the user.
|
|
53
|
+
*
|
|
54
|
+
* @param user - The user to register.
|
|
55
|
+
*/
|
|
56
|
+
private async register (
|
|
57
|
+
user: UserRegister,
|
|
58
|
+
setDone: Dispatch<SetStateAction<boolean>>,
|
|
59
|
+
setError: Dispatch<SetStateAction<UserRegisterErrors>>
|
|
60
|
+
): Promise<void> {
|
|
61
|
+
try {
|
|
62
|
+
await this.securityService.register(user)
|
|
63
|
+
setDone(true)
|
|
64
|
+
} catch (error: any) {
|
|
65
|
+
setError(error.response?.data?.errors ?? {})
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|