@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,65 @@
|
|
|
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 { ISecurityService } from '../../services/contracts/ISecurityService'
|
|
7
|
+
import { definePage, IPage, IRouter, ReactIncomingEvent } from '@stone-js/use-react'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Login Page options.
|
|
11
|
+
*/
|
|
12
|
+
interface LoginPageOptions {
|
|
13
|
+
router: IRouter
|
|
14
|
+
blueprint: IBlueprint
|
|
15
|
+
securityService: ISecurityService
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Login Page component.
|
|
20
|
+
*/
|
|
21
|
+
export const LoginPage = ({ router, blueprint, securityService }: LoginPageOptions): IPage<ReactIncomingEvent> => ({
|
|
22
|
+
/**
|
|
23
|
+
* Render the component.
|
|
24
|
+
*
|
|
25
|
+
* @param options - The options for rendering the component.
|
|
26
|
+
* @returns The rendered component.
|
|
27
|
+
*/
|
|
28
|
+
render (): JSX.Element {
|
|
29
|
+
const [error, setError] = useState<boolean>(false)
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div>
|
|
33
|
+
<LoginForm
|
|
34
|
+
error={error}
|
|
35
|
+
onSubmit={async (user: UserLogin) => await login(router, blueprint, securityService, user, setError)}
|
|
36
|
+
/>
|
|
37
|
+
</div>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Login the user.
|
|
44
|
+
*
|
|
45
|
+
* @param user - The user to login.
|
|
46
|
+
*/
|
|
47
|
+
export async function login (
|
|
48
|
+
router: IRouter,
|
|
49
|
+
blueprint: IBlueprint,
|
|
50
|
+
securityService: ISecurityService,
|
|
51
|
+
user: UserLogin,
|
|
52
|
+
setError: Dispatch<SetStateAction<boolean>>
|
|
53
|
+
): Promise<void> {
|
|
54
|
+
try {
|
|
55
|
+
await securityService.login(user)
|
|
56
|
+
router.navigate(blueprint.get('app.requestedUrl', '/'), true)
|
|
57
|
+
} catch (_: any) {
|
|
58
|
+
setError(true)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Login Page Blueprint.
|
|
64
|
+
*/
|
|
65
|
+
export const LoginPageBlueprint = definePage(LoginPage, { path: '/login', layout: 'security' })
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { deletePost } from '../../utils'
|
|
3
|
+
import { Post } from '../../../models/Post'
|
|
4
|
+
import { User } from '../../../models/User'
|
|
5
|
+
import { ILogger, isNotEmpty } from '@stone-js/core'
|
|
6
|
+
import { PostCard } from '../../../components/PostCard/PostCard'
|
|
7
|
+
import { IPostService } from '../../../services/contracts/IPostService'
|
|
8
|
+
import { ICommentService } from '../../../services/contracts/ICommentService'
|
|
9
|
+
import { CommentWidget } from '../../../components/CommentWidget/CommentWidget'
|
|
10
|
+
import { definePage, IPage, IRouter, PageRenderContext, ReactIncomingEvent } from '@stone-js/use-react'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Show Post Page options.
|
|
14
|
+
*/
|
|
15
|
+
export interface ShowPostPageOptions {
|
|
16
|
+
router: IRouter
|
|
17
|
+
logger: ILogger
|
|
18
|
+
postService: IPostService
|
|
19
|
+
commentService: ICommentService
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Show Post Page component.
|
|
24
|
+
*/
|
|
25
|
+
export const ShowPostPage = ({ router, logger, postService, commentService }: ShowPostPageOptions): IPage<ReactIncomingEvent> => ({
|
|
26
|
+
/**
|
|
27
|
+
* Render the component.
|
|
28
|
+
*
|
|
29
|
+
* @param options - The options for rendering the component.
|
|
30
|
+
* @returns The rendered component.
|
|
31
|
+
*/
|
|
32
|
+
render ({ event }: PageRenderContext<Post>): JSX.Element {
|
|
33
|
+
const post = event.get<Post>('post')
|
|
34
|
+
const user = event.getUser<User>() ?? {} as unknown as User
|
|
35
|
+
|
|
36
|
+
// Render the component
|
|
37
|
+
if (isNotEmpty<Post>(post)) {
|
|
38
|
+
return (
|
|
39
|
+
<PostCard
|
|
40
|
+
key={post.id}
|
|
41
|
+
post={post}
|
|
42
|
+
currentUser={user}
|
|
43
|
+
onEdit={() => router.navigate(`/posts/${post.id}/edit`)}
|
|
44
|
+
onDelete={deletePost.bind(this, router, logger, postService, post)}
|
|
45
|
+
>
|
|
46
|
+
<CommentWidget post={post} currentUser={user} commentService={commentService} />
|
|
47
|
+
</PostCard>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return <article><h1>Post not found</h1></article>
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Show Post Page Blueprint.
|
|
57
|
+
*/
|
|
58
|
+
export const ShowPostPageBlueprint = definePage(
|
|
59
|
+
ShowPostPage,
|
|
60
|
+
{
|
|
61
|
+
path: '/posts/:post@id(\\d+)',
|
|
62
|
+
bindings: { post: 'postService@findBy' }
|
|
63
|
+
}
|
|
64
|
+
)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { updatePost } from '../../utils'
|
|
3
|
+
import { Post } from '../../../models/Post'
|
|
4
|
+
import { ILogger, isNotEmpty } from '@stone-js/core'
|
|
5
|
+
import { PostForm } from '../../../components/PostForm/PostForm'
|
|
6
|
+
import { IPostService } from '../../../services/contracts/IPostService'
|
|
7
|
+
import { IPage, ReactIncomingEvent, PageRenderContext, definePage } from '@stone-js/use-react'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Update Post Page options.
|
|
11
|
+
*/
|
|
12
|
+
export interface UpdatePostPageOptions {
|
|
13
|
+
logger: ILogger
|
|
14
|
+
postService: IPostService
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Update Post Page component.
|
|
19
|
+
*/
|
|
20
|
+
export const UpdatePostPage = ({ logger, postService }: UpdatePostPageOptions): IPage<ReactIncomingEvent> => ({
|
|
21
|
+
/**
|
|
22
|
+
* Render the component.
|
|
23
|
+
*
|
|
24
|
+
* @param options - The options for rendering the component.
|
|
25
|
+
* @returns The rendered component.
|
|
26
|
+
*/
|
|
27
|
+
render ({ event }: PageRenderContext<Post>): JSX.Element {
|
|
28
|
+
const post = event.get<Post>('post')
|
|
29
|
+
|
|
30
|
+
if (isNotEmpty<Post>(post)) {
|
|
31
|
+
return (
|
|
32
|
+
<PostForm
|
|
33
|
+
post={post}
|
|
34
|
+
onSubmit={async (postInput) => await updatePost(logger, postService, post.id, postInput)}
|
|
35
|
+
/>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<article>
|
|
41
|
+
<h1>Post not found</h1>
|
|
42
|
+
</article>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Update Post Page Blueprint.
|
|
49
|
+
*/
|
|
50
|
+
export const UpdatePostPageBlueprint = definePage(
|
|
51
|
+
UpdatePostPage,
|
|
52
|
+
{
|
|
53
|
+
path: '/posts/:post@id(\\d+)/edit',
|
|
54
|
+
bindings: { post: 'postService@findBy' }
|
|
55
|
+
}
|
|
56
|
+
)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Dispatch, JSX, SetStateAction, useState } from 'react'
|
|
2
|
+
import { UserRegister, UserRegisterErrors } from '../../models/User'
|
|
3
|
+
import { RegisterForm } from '../../components/RegisterForm/RegisterForm'
|
|
4
|
+
import { definePage, IPage, ReactIncomingEvent } from '@stone-js/use-react'
|
|
5
|
+
import { ISecurityService } from '../../services/contracts/ISecurityService'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Register Page options.
|
|
9
|
+
*/
|
|
10
|
+
interface RegisterPageOptions {
|
|
11
|
+
securityService: ISecurityService
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Register Page component.
|
|
16
|
+
*/
|
|
17
|
+
export const RegisterPage = ({ securityService }: RegisterPageOptions): IPage<ReactIncomingEvent> => ({
|
|
18
|
+
/**
|
|
19
|
+
* Render the component.
|
|
20
|
+
*
|
|
21
|
+
* @param options - The options for rendering the component.
|
|
22
|
+
* @returns The rendered component.
|
|
23
|
+
*/
|
|
24
|
+
render (): JSX.Element {
|
|
25
|
+
const [done, setDone] = useState<boolean>(false)
|
|
26
|
+
const [error, setError] = useState<UserRegisterErrors>({})
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div>
|
|
30
|
+
<RegisterForm
|
|
31
|
+
done={done}
|
|
32
|
+
error={error}
|
|
33
|
+
onSubmit={async (user: UserRegister) => await register(securityService, user, setDone, setError)}
|
|
34
|
+
/>
|
|
35
|
+
</div>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Register the user.
|
|
42
|
+
*
|
|
43
|
+
* @param securityService - The security service.
|
|
44
|
+
* @param user - The user to register.
|
|
45
|
+
* @param setDone - The function to set the done state.
|
|
46
|
+
* @param setError - The function to set the error state.
|
|
47
|
+
*/
|
|
48
|
+
export async function register (
|
|
49
|
+
securityService: ISecurityService,
|
|
50
|
+
user: UserRegister,
|
|
51
|
+
setDone: Dispatch<SetStateAction<boolean>>,
|
|
52
|
+
setError: Dispatch<SetStateAction<UserRegisterErrors>>
|
|
53
|
+
): Promise<void> {
|
|
54
|
+
try {
|
|
55
|
+
await securityService.register(user)
|
|
56
|
+
setDone(true)
|
|
57
|
+
} catch (error: any) {
|
|
58
|
+
setError(error.response?.data?.errors ?? {})
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Register Page Blueprint.
|
|
64
|
+
*/
|
|
65
|
+
export const RegisterPageBlueprint = definePage(
|
|
66
|
+
RegisterPage,
|
|
67
|
+
{
|
|
68
|
+
path: '/register',
|
|
69
|
+
layout: 'security'
|
|
70
|
+
}
|
|
71
|
+
)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
.user-profile-page {
|
|
2
|
+
max-width: 768px;
|
|
3
|
+
margin: 0 auto;
|
|
4
|
+
padding: 0 1rem;
|
|
5
|
+
position: relative;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/* Cover Banner */
|
|
9
|
+
.profile-cover {
|
|
10
|
+
width: 100%;
|
|
11
|
+
height: 200px;
|
|
12
|
+
border-radius: 12px 12px 0 0;
|
|
13
|
+
background: linear-gradient(to right, #3b82f6, #6366f1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* Header with avatar */
|
|
17
|
+
.profile-header {
|
|
18
|
+
background: white;
|
|
19
|
+
margin-top: -48px;
|
|
20
|
+
padding: 1.5rem;
|
|
21
|
+
border-radius: 12px;
|
|
22
|
+
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
gap: 1.5rem;
|
|
26
|
+
flex-wrap: wrap;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.profile-avatar {
|
|
30
|
+
margin-top: -24px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.profile-info h1 {
|
|
34
|
+
font-size: 1.5rem;
|
|
35
|
+
font-weight: 700;
|
|
36
|
+
margin-bottom: 0.25rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.profile-info .email {
|
|
40
|
+
font-size: 0.9rem;
|
|
41
|
+
color: #6b7280;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.profile-info .bio {
|
|
45
|
+
font-size: 1rem;
|
|
46
|
+
color: #374151;
|
|
47
|
+
margin-top: 0.5rem;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.profile-info .status {
|
|
51
|
+
font-size: 0.85rem;
|
|
52
|
+
color: #6b7280;
|
|
53
|
+
margin-top: 0.25rem;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.profile-info .online {
|
|
57
|
+
color: #10b981;
|
|
58
|
+
font-weight: 600;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* Timeline Section */
|
|
62
|
+
.profile-timeline {
|
|
63
|
+
margin-top: 2rem;
|
|
64
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { createPost } from '../../utils'
|
|
3
|
+
import { User } from '../../../models/User'
|
|
4
|
+
import { Post } from '../../../models/Post'
|
|
5
|
+
import { dateTimeFromNow } from '../../../utils'
|
|
6
|
+
import { ILogger, isNotEmpty } from '@stone-js/core'
|
|
7
|
+
import { PostForm } from '../../../components/PostForm/PostForm'
|
|
8
|
+
import { UserAvatar } from '../../../components/UserAvatar/UserAvatar'
|
|
9
|
+
import { PostWidget } from '../../../components/PostWidget/PostWidget'
|
|
10
|
+
import { IPostService } from '../../../services/contracts/IPostService'
|
|
11
|
+
import { IUserService } from '../../../services/contracts/IUserService'
|
|
12
|
+
import { IPage, ReactIncomingEvent, PageRenderContext, definePage, HeadContext, IRouter } from '@stone-js/use-react'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Show User Page options.
|
|
16
|
+
*/
|
|
17
|
+
export interface ShowUserPageOptions {
|
|
18
|
+
router: IRouter
|
|
19
|
+
logger: ILogger
|
|
20
|
+
postService: IPostService
|
|
21
|
+
userService: IUserService
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Show User Page component.
|
|
26
|
+
*/
|
|
27
|
+
export const ShowUserPage = ({ router, logger, postService }: ShowUserPageOptions): IPage<ReactIncomingEvent> => ({
|
|
28
|
+
head (): HeadContext {
|
|
29
|
+
return {
|
|
30
|
+
title: 'User Profile',
|
|
31
|
+
description: 'Welcome to the user profile page'
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Handle the incoming event.
|
|
37
|
+
*
|
|
38
|
+
* @param event - The incoming event.
|
|
39
|
+
* @returns List of posts.
|
|
40
|
+
*/
|
|
41
|
+
async handle (event: ReactIncomingEvent): Promise<Post[]> {
|
|
42
|
+
return await postService.list(event.get<number>('limit', 10))
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Render the component.
|
|
47
|
+
*
|
|
48
|
+
* @param options - The options for rendering the component.
|
|
49
|
+
* @returns The rendered component.
|
|
50
|
+
*/
|
|
51
|
+
render ({ data, event, container }: PageRenderContext): JSX.Element {
|
|
52
|
+
const user = event.get<User>('user') ?? {} as unknown as User
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className='user-profile-page'>
|
|
56
|
+
<div className='profile-cover' />
|
|
57
|
+
|
|
58
|
+
<div className='profile-header'>
|
|
59
|
+
<div className='profile-avatar'>
|
|
60
|
+
<UserAvatar user={user} size={96} />
|
|
61
|
+
</div>
|
|
62
|
+
<div className='profile-info'>
|
|
63
|
+
<h1>{user.name}</h1>
|
|
64
|
+
<p className='email'>{user.email}</p>
|
|
65
|
+
{user.bio !== undefined && <p className='bio'>{user.bio}</p>}
|
|
66
|
+
<p className='status'>
|
|
67
|
+
{user.isOnline
|
|
68
|
+
? <span className='online'>🟢 Online</span>
|
|
69
|
+
: `Last seen ${dateTimeFromNow(user.lastSeen)}`}
|
|
70
|
+
</p>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<section className='profile-timeline'>
|
|
75
|
+
<PostForm onSubmit={createPost.bind(this, router, logger, postService)} />
|
|
76
|
+
<PostWidget items={data ?? []} event={event} container={container} />
|
|
77
|
+
</section>
|
|
78
|
+
</div>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Delete the user.
|
|
85
|
+
*
|
|
86
|
+
* @param container - The container.
|
|
87
|
+
* @param user - The user
|
|
88
|
+
*/
|
|
89
|
+
export async function deleteUser (userService: IUserService, user?: User): Promise<void> {
|
|
90
|
+
if (isNotEmpty<User>(user) && window.confirm('Are you sure you want to delete this user?')) {
|
|
91
|
+
await userService.delete(user.id)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Show User Page Blueprint.
|
|
97
|
+
*/
|
|
98
|
+
export const ShowUserPageBlueprint = definePage(
|
|
99
|
+
ShowUserPage,
|
|
100
|
+
{
|
|
101
|
+
path: '/users/:user@id(\\d+)',
|
|
102
|
+
bindings: { user: 'userService@findBy' }
|
|
103
|
+
}
|
|
104
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { JSX } from 'react'
|
|
2
|
+
import { User, UserInput } from '../../../models/User'
|
|
3
|
+
import { IUserService } from '../../../services/contracts/IUserService'
|
|
4
|
+
import { ProfileForm } from '../../../components/ProfileForm/ProfileForm'
|
|
5
|
+
import { IPage, ReactIncomingEvent, PageRenderContext, definePage } from '@stone-js/use-react'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Update User Page options.
|
|
9
|
+
*/
|
|
10
|
+
export interface UpdateUserPageOptions {
|
|
11
|
+
userService: IUserService
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Update User Page component.
|
|
16
|
+
*/
|
|
17
|
+
export const UpdateUserPage = (): IPage<ReactIncomingEvent> => ({
|
|
18
|
+
/**
|
|
19
|
+
* Render the component.
|
|
20
|
+
*
|
|
21
|
+
* @param options - The options for rendering the component.
|
|
22
|
+
* @returns The rendered component.
|
|
23
|
+
*/
|
|
24
|
+
render ({ event }: PageRenderContext): JSX.Element {
|
|
25
|
+
const user = event.get<User>('user') ?? {} as unknown as User
|
|
26
|
+
|
|
27
|
+
return <ProfileForm user={user} onSave={() => {}} />
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Save the user.
|
|
33
|
+
*
|
|
34
|
+
* @param user - The user
|
|
35
|
+
*/
|
|
36
|
+
export async function saveUser (userService: IUserService, id: number, user: UserInput): Promise<void> {
|
|
37
|
+
await userService.update(id, user)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Update User Page Blueprint.
|
|
42
|
+
*/
|
|
43
|
+
export const UpdateUserPageBlueprint = definePage(UpdateUserPage, { path: '/users/:user@id(\\d+)/edit' })
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
.users-page .users-title {
|
|
2
|
+
font-size: 2rem;
|
|
3
|
+
font-weight: 700;
|
|
4
|
+
color: #111827;
|
|
5
|
+
margin-bottom: 2rem;
|
|
6
|
+
text-align: left;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.users-search {
|
|
10
|
+
display: block;
|
|
11
|
+
width: 100%;
|
|
12
|
+
padding: 0.75rem 1.25rem;
|
|
13
|
+
font-size: 1rem;
|
|
14
|
+
border-radius: 9999px;
|
|
15
|
+
border: 1px solid #d1d5db;
|
|
16
|
+
background-color: #f9fafb;
|
|
17
|
+
margin-bottom: 2rem;
|
|
18
|
+
outline: none;
|
|
19
|
+
transition: border-color 0.2s ease;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.users-search:focus {
|
|
23
|
+
border-color: #3b82f6;
|
|
24
|
+
background-color: #ffffff;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.users-page .user-grid {
|
|
28
|
+
display: grid;
|
|
29
|
+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
30
|
+
gap: 1.5rem;
|
|
31
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import './UserPage.css'
|
|
2
|
+
import { JSX, useState } from 'react'
|
|
3
|
+
import { User } from '../../../models/User'
|
|
4
|
+
import { UserCard } from '../../../components/UserCard/UserCard'
|
|
5
|
+
import { IUserService } from '../../../services/contracts/IUserService'
|
|
6
|
+
import { IPage, definePage, ReactIncomingEvent, PageRenderContext } from '@stone-js/use-react'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* User Page options.
|
|
10
|
+
*/
|
|
11
|
+
export interface UserPageOptions {
|
|
12
|
+
userService: IUserService
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* User Page component.
|
|
17
|
+
*/
|
|
18
|
+
export const UserPage = ({ userService }: { userService: IUserService }): IPage<ReactIncomingEvent> => ({
|
|
19
|
+
/**
|
|
20
|
+
* Handle the incoming event.
|
|
21
|
+
*
|
|
22
|
+
* @param event - The incoming event.
|
|
23
|
+
* @returns The event data.
|
|
24
|
+
*/
|
|
25
|
+
async handle (event: ReactIncomingEvent): Promise<User[]> {
|
|
26
|
+
return await userService.list(event.get<number>('limit', 10))
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Render the component.
|
|
31
|
+
*
|
|
32
|
+
* @param options - The options for rendering the component.
|
|
33
|
+
* @returns The rendered component.
|
|
34
|
+
*/
|
|
35
|
+
render ({ data }: PageRenderContext<User[]>): JSX.Element {
|
|
36
|
+
const [query, setQuery] = useState('')
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div className='users-page'>
|
|
40
|
+
<h1 className='users-title'>Users</h1>
|
|
41
|
+
<input
|
|
42
|
+
type='text'
|
|
43
|
+
placeholder='Search by name or email...'
|
|
44
|
+
value={query}
|
|
45
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
46
|
+
className='users-search'
|
|
47
|
+
/>
|
|
48
|
+
<div className='user-grid'>
|
|
49
|
+
{data?.map(user => (<UserCard key={user.id} user={user} />))}
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* User Page Blueprint.
|
|
58
|
+
*/
|
|
59
|
+
export const UserPageBlueprint = definePage(UserPage, { path: '/users' })
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ILogger } from '@stone-js/core'
|
|
2
|
+
import { IRouter } from '@stone-js/use-react'
|
|
3
|
+
import { PostInput, Post } from '../models/Post'
|
|
4
|
+
import { IPostService } from '../services/contracts/IPostService'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Create the post.
|
|
8
|
+
*
|
|
9
|
+
* @param post - The post to save.
|
|
10
|
+
*/
|
|
11
|
+
export async function createPost (
|
|
12
|
+
router: IRouter,
|
|
13
|
+
logger: ILogger,
|
|
14
|
+
postService: IPostService,
|
|
15
|
+
postInput: PostInput
|
|
16
|
+
): Promise<void> {
|
|
17
|
+
try {
|
|
18
|
+
const post = await postService.create(postInput)
|
|
19
|
+
router.navigate(`/posts/${post.id}`)
|
|
20
|
+
} catch (error: any) {
|
|
21
|
+
console.error(error)
|
|
22
|
+
window.alert('Error creating the post')
|
|
23
|
+
logger.error(error.message, { error })
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Delete the post.
|
|
29
|
+
*
|
|
30
|
+
* @param post - The post to delete.
|
|
31
|
+
*/
|
|
32
|
+
export async function deletePost (
|
|
33
|
+
router: IRouter,
|
|
34
|
+
logger: ILogger,
|
|
35
|
+
postService: IPostService,
|
|
36
|
+
post: Post
|
|
37
|
+
): Promise<void> {
|
|
38
|
+
if (window.confirm('Are you sure you want to delete this post?')) {
|
|
39
|
+
try {
|
|
40
|
+
await postService.delete(post.id)
|
|
41
|
+
router.navigate('/posts')
|
|
42
|
+
} catch (error: any) {
|
|
43
|
+
window.alert('Error deleting the post')
|
|
44
|
+
logger.error(error.message, { error })
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Update the post.
|
|
51
|
+
*
|
|
52
|
+
* @param post - The post to update.
|
|
53
|
+
*/
|
|
54
|
+
export async function updatePost (
|
|
55
|
+
logger: ILogger,
|
|
56
|
+
postService: IPostService,
|
|
57
|
+
id: number,
|
|
58
|
+
post: PostInput
|
|
59
|
+
): Promise<void> {
|
|
60
|
+
try {
|
|
61
|
+
await postService.update(id, post)
|
|
62
|
+
window.alert('Post updated successfully')
|
|
63
|
+
} catch (error: any) {
|
|
64
|
+
window.alert('Error updating the post')
|
|
65
|
+
logger.error(error.message, { error })
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import axios, { AxiosInstance } from 'axios'
|
|
2
|
+
import { AxiosClient } from '../clients/AxiosClient'
|
|
3
|
+
import { defineServiceProvider, IBlueprint, IContainer, IServiceProvider } from '@stone-js/core'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get Axios instance
|
|
7
|
+
*
|
|
8
|
+
* @param container - The container
|
|
9
|
+
* @returns The Axios instance
|
|
10
|
+
*/
|
|
11
|
+
export function getAxiosInstance (container: IContainer): AxiosInstance {
|
|
12
|
+
const baseURL = container.make<IBlueprint>('blueprint').get<string>('app.api.baseURL', 'http://localhost:8080')
|
|
13
|
+
return axios.create({ baseURL })
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* App Service Provider
|
|
18
|
+
*/
|
|
19
|
+
export const AppServiceProvider = (container: IContainer): IServiceProvider => ({
|
|
20
|
+
/**
|
|
21
|
+
* Register services to the container
|
|
22
|
+
*/
|
|
23
|
+
register (): void {
|
|
24
|
+
container
|
|
25
|
+
.instanceIf('axios', getAxiosInstance(container))
|
|
26
|
+
.singletonIf(AxiosClient, (container) => {
|
|
27
|
+
return AxiosClient({
|
|
28
|
+
axios: container.make('axios'),
|
|
29
|
+
event: container.make('event'),
|
|
30
|
+
tokenService: container.make('tokenService')
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
.alias(AxiosClient, ['axiosClient', 'httpClient'])
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* App Service Provider Blueprint
|
|
39
|
+
*/
|
|
40
|
+
export const AppServiceProviderBlueprint = defineServiceProvider(AppServiceProvider)
|