@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,110 @@
|
|
|
1
|
+
import { FC, useState } from 'react'
|
|
2
|
+
import { isNotEmpty } from '@stone-js/core'
|
|
3
|
+
import { StoneLink } from '@stone-js/use-react'
|
|
4
|
+
import { UserRegister, UserRegisterErrors } from '../../models/User'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Register Form Options
|
|
8
|
+
*/
|
|
9
|
+
export interface RegisterFormOptions {
|
|
10
|
+
done: boolean
|
|
11
|
+
error?: UserRegisterErrors
|
|
12
|
+
onSubmit: (user: UserRegister) => Promise<void>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Register Form component.
|
|
17
|
+
*
|
|
18
|
+
* @param options - The options to create the Register Form component.
|
|
19
|
+
*/
|
|
20
|
+
export const RegisterForm: FC<RegisterFormOptions> = ({ onSubmit, error, done }) => {
|
|
21
|
+
// Create a reference to the user
|
|
22
|
+
const [user, setUser] = useState<UserRegister>({
|
|
23
|
+
name: '',
|
|
24
|
+
email: '',
|
|
25
|
+
password: '',
|
|
26
|
+
confirmPassword: ''
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// Handle the form submit
|
|
30
|
+
const handleSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
|
|
31
|
+
event.preventDefault()
|
|
32
|
+
isValid() && onSubmit(user).catch(() => {})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const isValid = (): boolean => isNotEmpty(user.name) && isNotEmpty(user.email) && isNotEmpty(user.password) && user.password === user.confirmPassword
|
|
36
|
+
|
|
37
|
+
// Handle the field change
|
|
38
|
+
const onChange = (field: keyof UserRegister) => (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
39
|
+
setUser({ ...user, [field]: event.target.value })
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Create the form component
|
|
43
|
+
const formComponent = (
|
|
44
|
+
<form onSubmit={handleSubmit} className='panel'>
|
|
45
|
+
{error?.message !== undefined && <p className='alert alert-danger alert-small'>{error?.message}</p>}
|
|
46
|
+
|
|
47
|
+
<div>
|
|
48
|
+
<label htmlFor='name' className='label'>Name:</label>
|
|
49
|
+
<input
|
|
50
|
+
id='name'
|
|
51
|
+
type='text'
|
|
52
|
+
className='input'
|
|
53
|
+
placeholder='Enter your name'
|
|
54
|
+
onChange={onChange('name')} defaultValue={user.name}
|
|
55
|
+
/>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<div>
|
|
59
|
+
<label htmlFor='email' className='label'>Email:</label>
|
|
60
|
+
<input
|
|
61
|
+
id='email'
|
|
62
|
+
type='email'
|
|
63
|
+
className='input'
|
|
64
|
+
placeholder='Enter your email'
|
|
65
|
+
onChange={onChange('email')} defaultValue={user.email}
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<div>
|
|
70
|
+
<label htmlFor='password' className='label'>Password:</label>
|
|
71
|
+
<input
|
|
72
|
+
id='password'
|
|
73
|
+
type='password'
|
|
74
|
+
className='input'
|
|
75
|
+
placeholder='Enter your password'
|
|
76
|
+
onChange={onChange('password')} defaultValue={user.password}
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<div>
|
|
81
|
+
<label htmlFor='confirmPassword' className='label'>Confirm password:</label>
|
|
82
|
+
<input
|
|
83
|
+
id='confirmPassword'
|
|
84
|
+
type='password'
|
|
85
|
+
className='input'
|
|
86
|
+
placeholder='Confirm your password'
|
|
87
|
+
onChange={onChange('confirmPassword')} defaultValue={user.confirmPassword}
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<button type='submit' className='button button-secondary button-full mt-24' disabled={!isValid()}>Register</button>
|
|
92
|
+
</form>
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
// Create the done component
|
|
96
|
+
const doneComponent = <div className='panel'><p className='alert alert-success'>Registration successful! 🎉 You can now login</p></div>
|
|
97
|
+
|
|
98
|
+
// Get the component
|
|
99
|
+
const component = done ? doneComponent : formComponent
|
|
100
|
+
|
|
101
|
+
// Render the component
|
|
102
|
+
return (
|
|
103
|
+
<div>
|
|
104
|
+
{component}
|
|
105
|
+
<p className='mt-24 text-center'>
|
|
106
|
+
<StoneLink to='/login' className='button button-primary'>Login</StoneLink>
|
|
107
|
+
</p>
|
|
108
|
+
</div>
|
|
109
|
+
)
|
|
110
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { FC, useRef } from 'react'
|
|
2
|
+
import { UserInput } from '../../models/User'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* User Form Options
|
|
6
|
+
*/
|
|
7
|
+
export interface UserFormOptions {
|
|
8
|
+
user?: UserInput
|
|
9
|
+
onSubmit: (user: UserInput) => Promise<void>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* User Form component.
|
|
14
|
+
*
|
|
15
|
+
* @param options - The options to create the User Form component.
|
|
16
|
+
*/
|
|
17
|
+
export const UserForm: FC<UserFormOptions> = ({ user, onSubmit }) => {
|
|
18
|
+
// Create a reference to the user
|
|
19
|
+
const userRef = useRef<UserInput>({
|
|
20
|
+
name: user?.name ?? '',
|
|
21
|
+
email: user?.email ?? ''
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// Handle the form submit
|
|
25
|
+
const handleSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
|
|
26
|
+
event.preventDefault()
|
|
27
|
+
void onSubmit(userRef.current).catch(() => {})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Handle the field change
|
|
31
|
+
const onChange = (field: keyof UserInput) => (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
32
|
+
userRef.current[field] = event.target.value
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Render the component
|
|
36
|
+
return (
|
|
37
|
+
<form onSubmit={handleSubmit}>
|
|
38
|
+
<label htmlFor='name'>Name:</label>
|
|
39
|
+
<input id='name' type='text' onChange={onChange('name')} defaultValue={userRef.current.name} />
|
|
40
|
+
|
|
41
|
+
<label htmlFor='email'>Email:</label>
|
|
42
|
+
<input id='email' type='email' onChange={onChange('email')} defaultValue={userRef.current.email} />
|
|
43
|
+
|
|
44
|
+
<button type='submit'>Save</button>
|
|
45
|
+
</form>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getString } from '@stone-js/env'
|
|
2
|
+
import { Configuration, IBlueprint, IConfiguration, Promiseable } from '@stone-js/core'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* App Configuration
|
|
6
|
+
*/
|
|
7
|
+
@Configuration()
|
|
8
|
+
export class AppConfiguration implements IConfiguration {
|
|
9
|
+
/**
|
|
10
|
+
* Configure the application.
|
|
11
|
+
*/
|
|
12
|
+
configure (blueprint: IBlueprint): Promiseable<void> {
|
|
13
|
+
blueprint
|
|
14
|
+
.set('stone.kernel.skipMiddleware', false)
|
|
15
|
+
.set('app.api.baseURL', getString('API_BASE_URL', 'http://localhost:8080'))
|
|
16
|
+
}
|
|
17
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import './DefaultErrorPage.css'
|
|
2
|
+
import { JSX } from 'react'
|
|
3
|
+
import { ILogger } from '@stone-js/core'
|
|
4
|
+
import { ErrorPage, IErrorPage, PageStatus, ReactIncomingEvent, ErrorPageRenderContext } from '@stone-js/use-react'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Forbidden Error Handler component.
|
|
8
|
+
*/
|
|
9
|
+
@ErrorPage({
|
|
10
|
+
layout: 'error',
|
|
11
|
+
error: 'default'
|
|
12
|
+
})
|
|
13
|
+
export class DefaultErrorPage implements IErrorPage<ReactIncomingEvent> {
|
|
14
|
+
private readonly logger: ILogger
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Create an DefaultErrorPage.
|
|
18
|
+
*
|
|
19
|
+
* @param logger - The logger.
|
|
20
|
+
*/
|
|
21
|
+
constructor ({ logger }: { logger: ILogger }) {
|
|
22
|
+
this.logger = logger
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Handle the error.
|
|
27
|
+
*
|
|
28
|
+
* @param error - The error to handle.
|
|
29
|
+
* @returns The response.
|
|
30
|
+
*/
|
|
31
|
+
@PageStatus(500)
|
|
32
|
+
handle (error: any): { message: string } {
|
|
33
|
+
this.logger.error(error.message, { error })
|
|
34
|
+
return { message: 'Oops! Something went wrong!' }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Render the component.
|
|
39
|
+
*
|
|
40
|
+
* @param options - The options for rendering the component.
|
|
41
|
+
* @returns The rendered component.
|
|
42
|
+
*/
|
|
43
|
+
render ({ data, statusCode }: ErrorPageRenderContext<Error>): JSX.Element {
|
|
44
|
+
return (
|
|
45
|
+
<div className='text-center'>
|
|
46
|
+
<h1 className='h1'>{statusCode}</h1>
|
|
47
|
+
<h2 className='h4'>An Error occured!</h2>
|
|
48
|
+
<p className='text-muted mt-24'>{data?.message}</p>
|
|
49
|
+
</div>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import './ForbiddenErrorPage.css'
|
|
2
|
+
import { JSX } from 'react'
|
|
3
|
+
import { ILogger } from '@stone-js/core'
|
|
4
|
+
import { ForbiddenError } from '../../errors/ForbiddenError'
|
|
5
|
+
import { ErrorPage, IErrorPage, PageStatus, ReactIncomingEvent, ErrorPageRenderContext } from '@stone-js/use-react'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Forbidden Error Handler component.
|
|
9
|
+
*/
|
|
10
|
+
@ErrorPage({
|
|
11
|
+
layout: 'error',
|
|
12
|
+
error: 'ForbiddenError'
|
|
13
|
+
})
|
|
14
|
+
export class ForbiddenErrorPage implements IErrorPage<ReactIncomingEvent> {
|
|
15
|
+
private readonly logger: ILogger
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create an ForbiddenErrorPage.
|
|
19
|
+
*
|
|
20
|
+
* @param logger - The logger.
|
|
21
|
+
*/
|
|
22
|
+
constructor ({ logger }: { logger: ILogger }) {
|
|
23
|
+
this.logger = logger
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Handle the error.
|
|
28
|
+
*
|
|
29
|
+
* @param error - The error to handle.
|
|
30
|
+
* @returns The response.
|
|
31
|
+
*/
|
|
32
|
+
@PageStatus(403)
|
|
33
|
+
handle (error: ForbiddenError): { message: string } {
|
|
34
|
+
this.logger.error(error.message, { error })
|
|
35
|
+
return { message: "I think you're not supposed to be here! Eh ?" }
|
|
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 ({ data, statusCode }: ErrorPageRenderContext<ForbiddenError>): JSX.Element {
|
|
45
|
+
return (
|
|
46
|
+
<div className='text-center'>
|
|
47
|
+
<h1 className='h1'>{statusCode}</h1>
|
|
48
|
+
<h2 className='h4'>Are you in the right place?</h2>
|
|
49
|
+
<p className='text-muted mt-24'>{data?.message}</p>
|
|
50
|
+
</div>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import './NotFoundErrorPage.css'
|
|
2
|
+
import { JSX } from 'react'
|
|
3
|
+
import { ILogger } from '@stone-js/core'
|
|
4
|
+
import { RouteNotFoundError } from '@stone-js/router'
|
|
5
|
+
import { ErrorPage, IErrorPage, PageStatus, ReactIncomingEvent, ErrorPageRenderContext } from '@stone-js/use-react'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* NotFound Error Handler component.
|
|
9
|
+
*/
|
|
10
|
+
@ErrorPage({
|
|
11
|
+
layout: 'error',
|
|
12
|
+
error: ['RouteNotFoundError', 'PostNotFoundError', 'UserNotFoundError']
|
|
13
|
+
})
|
|
14
|
+
export class NotFoundErrorPage implements IErrorPage<ReactIncomingEvent> {
|
|
15
|
+
private readonly logger: ILogger
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create an NotFoundErrorPage.
|
|
19
|
+
*
|
|
20
|
+
* @param logger - The logger.
|
|
21
|
+
*/
|
|
22
|
+
constructor ({ logger }: { logger: ILogger }) {
|
|
23
|
+
this.logger = logger
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Handle the error.
|
|
28
|
+
*
|
|
29
|
+
* @param error - The error to handle.
|
|
30
|
+
* @param event - The incoming event.
|
|
31
|
+
* @returns The response.
|
|
32
|
+
*/
|
|
33
|
+
@PageStatus(404)
|
|
34
|
+
handle (error: RouteNotFoundError, event: ReactIncomingEvent): { message: string } {
|
|
35
|
+
this.logger.error(error.message, { error })
|
|
36
|
+
return { message: `Page not found: ${event.pathname}` }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Render the component.
|
|
41
|
+
*
|
|
42
|
+
* @param options - The options for rendering the component.
|
|
43
|
+
* @returns The rendered component.
|
|
44
|
+
*/
|
|
45
|
+
render ({ data, statusCode }: ErrorPageRenderContext<RouteNotFoundError>): JSX.Element {
|
|
46
|
+
return (
|
|
47
|
+
<div className='text-center'>
|
|
48
|
+
<h1 className='h1'>{statusCode}</h1>
|
|
49
|
+
<h2 className='h4'>OOps! It seems you are lost?</h2>
|
|
50
|
+
<p className='text-muted mt-24'>{data?.message}</p>
|
|
51
|
+
</div>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
}
|
package/full-react-declarative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.css
ADDED
|
File without changes
|
package/full-react-declarative/app/error-pages/UnauthorizedErrorPage/UnauthorizedErrorPage.tsx
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import './UnauthorizedErrorPage.css'
|
|
2
|
+
import { JSX } from 'react'
|
|
3
|
+
import { ILogger } from '@stone-js/core'
|
|
4
|
+
import { UnauthorizedError } from '../../errors/UnauthorizedError'
|
|
5
|
+
import { ErrorPage, IErrorPage, PageStatus, ReactIncomingEvent, ErrorPageRenderContext } from '@stone-js/use-react'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Unauthorized Error Handler component.
|
|
9
|
+
*/
|
|
10
|
+
@ErrorPage({
|
|
11
|
+
layout: 'error',
|
|
12
|
+
error: 'UnauthorizedError'
|
|
13
|
+
})
|
|
14
|
+
export class UnauthorizedErrorPage implements IErrorPage<ReactIncomingEvent> {
|
|
15
|
+
private readonly logger: ILogger
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create an UnauthorizedErrorPage.
|
|
19
|
+
*
|
|
20
|
+
* @param logger - The logger.
|
|
21
|
+
*/
|
|
22
|
+
constructor ({ logger }: { logger: ILogger }) {
|
|
23
|
+
this.logger = logger
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Handle the error.
|
|
28
|
+
*
|
|
29
|
+
* @param error - The error to handle.
|
|
30
|
+
* @returns The response.
|
|
31
|
+
*/
|
|
32
|
+
@PageStatus(403)
|
|
33
|
+
handle (error: UnauthorizedError): { message: string } {
|
|
34
|
+
this.logger.error(error.message, { error })
|
|
35
|
+
return { message: "I think you're an alien! Eh ?" }
|
|
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 ({ data, statusCode }: ErrorPageRenderContext<UnauthorizedError>): JSX.Element {
|
|
45
|
+
return (
|
|
46
|
+
<div className='text-center'>
|
|
47
|
+
<h1 className='h1'>{statusCode}</h1>
|
|
48
|
+
<h2 className='h4'>Are you in the right place?</h2>
|
|
49
|
+
<p className='text-muted mt-24'>{data?.message}</p>
|
|
50
|
+
</div>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ErrorOptions, RuntimeError } from '@stone-js/core'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Not Forbidden Error
|
|
5
|
+
*/
|
|
6
|
+
export class ForbiddenError extends RuntimeError {
|
|
7
|
+
constructor (message: string, options?: ErrorOptions) {
|
|
8
|
+
super(message, options)
|
|
9
|
+
this.name = 'ForbiddenError'
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ErrorOptions, RuntimeError } from '@stone-js/core'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Post Not found Error
|
|
5
|
+
*/
|
|
6
|
+
export class PostNotFoundError extends RuntimeError {
|
|
7
|
+
constructor (message: string, options: ErrorOptions = {}) {
|
|
8
|
+
super(message, options)
|
|
9
|
+
this.name = 'PostNotFoundError'
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ErrorOptions, RuntimeError } from '@stone-js/core'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Unauthorized Error
|
|
5
|
+
*/
|
|
6
|
+
export class UnauthorizedError extends RuntimeError {
|
|
7
|
+
constructor (message: string, options?: ErrorOptions) {
|
|
8
|
+
super(message, options)
|
|
9
|
+
this.name = 'UnauthorizedError'
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ErrorOptions, RuntimeError } from '@stone-js/core'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* User Not found Error
|
|
5
|
+
*/
|
|
6
|
+
export class UserNotFoundError extends RuntimeError {
|
|
7
|
+
constructor (message: string, options: ErrorOptions = {}) {
|
|
8
|
+
super(message, options)
|
|
9
|
+
this.name = 'UserNotFoundError'
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { User } from '../models/User'
|
|
2
|
+
import { Event } from '@stone-js/core'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* User Event
|
|
6
|
+
*/
|
|
7
|
+
export class UserEvent extends Event {
|
|
8
|
+
/**
|
|
9
|
+
* USER_CREATED Event name, fires after a user have been created.
|
|
10
|
+
*
|
|
11
|
+
* @event UserEvent#USER_CREATED
|
|
12
|
+
*/
|
|
13
|
+
static USER_CREATED: string = 'user.created'
|
|
14
|
+
|
|
15
|
+
constructor (public readonly user: Partial<User>) {
|
|
16
|
+
super({ type: UserEvent.USER_CREATED })
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.app-layout .logo {
|
|
2
|
+
margin: 0;
|
|
3
|
+
border: none;
|
|
4
|
+
display: flex;
|
|
5
|
+
width: 300px;
|
|
6
|
+
align-items: center;
|
|
7
|
+
background: none;
|
|
8
|
+
text-align: center;
|
|
9
|
+
}
|
|
10
|
+
.app-layout .logo:hover {
|
|
11
|
+
cursor: pointer;
|
|
12
|
+
}
|
|
13
|
+
.app-layout .logo img {
|
|
14
|
+
width: 24px;
|
|
15
|
+
}
|
|
16
|
+
.app-layout .logo span {
|
|
17
|
+
font-size: 1.5em;
|
|
18
|
+
margin-left: 8px;
|
|
19
|
+
font-weight: bold;
|
|
20
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import './AppLayout.css'
|
|
2
|
+
import { JSX } from 'react'
|
|
3
|
+
import { User } from '../../models/User'
|
|
4
|
+
import { IBlueprint, isNotEmpty } from '@stone-js/core'
|
|
5
|
+
import { SecurityService } from '../../services/SecurityService'
|
|
6
|
+
import { IPageLayout, IRouter, PageLayout, PageLayoutRenderContext, ReactIncomingEvent, StoneLink, StoneOutlet } from '@stone-js/use-react'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* App Layout options.
|
|
10
|
+
*/
|
|
11
|
+
export interface AppLayoutOptions {
|
|
12
|
+
router: IRouter
|
|
13
|
+
blueprint: IBlueprint
|
|
14
|
+
securityService: SecurityService
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* App Layout component.
|
|
19
|
+
*/
|
|
20
|
+
@PageLayout({ name: 'default' })
|
|
21
|
+
export class AppLayout implements IPageLayout {
|
|
22
|
+
private readonly router: IRouter
|
|
23
|
+
private readonly blueprint: IBlueprint
|
|
24
|
+
private readonly securityService: SecurityService
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Create a new App Layout component.
|
|
28
|
+
*
|
|
29
|
+
* @param options - The options to create the App Layout component.
|
|
30
|
+
*/
|
|
31
|
+
constructor ({ router, blueprint, securityService }: AppLayoutOptions) {
|
|
32
|
+
this.router = router
|
|
33
|
+
this.blueprint = blueprint
|
|
34
|
+
this.securityService = securityService
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Render the component.
|
|
39
|
+
*
|
|
40
|
+
* @param options - The options for rendering the component.
|
|
41
|
+
* @returns The rendered component.
|
|
42
|
+
*/
|
|
43
|
+
render ({ container, children }: PageLayoutRenderContext): JSX.Element {
|
|
44
|
+
const user = container.make<ReactIncomingEvent>('event').getUser<User>() ?? {} as unknown as User
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<div className='app-layout'>
|
|
48
|
+
<header>
|
|
49
|
+
<p>
|
|
50
|
+
<StoneLink to='/' className='logo'>
|
|
51
|
+
<img src='/logo.png' alt='Stone.js Logo' />
|
|
52
|
+
<span>Stone.js</span>
|
|
53
|
+
</StoneLink>
|
|
54
|
+
</p>
|
|
55
|
+
{isNotEmpty<User>(user) && (
|
|
56
|
+
<p>
|
|
57
|
+
<span>
|
|
58
|
+
<img src={this.getUserAvatar(user)} alt='Stone.js Logo' />
|
|
59
|
+
</span>
|
|
60
|
+
<span>
|
|
61
|
+
<span>{user.name}</span>
|
|
62
|
+
<span>{user.email}</span>
|
|
63
|
+
</span>
|
|
64
|
+
</p>
|
|
65
|
+
)}
|
|
66
|
+
<p>
|
|
67
|
+
{isNotEmpty<User>(user)
|
|
68
|
+
? <button onClick={() => this.logout()}>Logout</button>
|
|
69
|
+
: <StoneLink to='/login'>Login</StoneLink>}
|
|
70
|
+
</p>
|
|
71
|
+
</header>
|
|
72
|
+
<main>
|
|
73
|
+
<StoneOutlet>{children}</StoneOutlet>
|
|
74
|
+
</main>
|
|
75
|
+
<footer>© 2025 Stone.js</footer>
|
|
76
|
+
</div>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Logout the user.
|
|
82
|
+
*/
|
|
83
|
+
logout (): void {
|
|
84
|
+
if (window.confirm('Are you sure you want to logout?')) {
|
|
85
|
+
void this.securityService.logout().then(() => {
|
|
86
|
+
this.router.navigate('/', true)
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get the user avatar.
|
|
93
|
+
*
|
|
94
|
+
* @param user - The user to get the avatar.
|
|
95
|
+
* @returns The user avatar.
|
|
96
|
+
*/
|
|
97
|
+
private getUserAvatar (user: User): string {
|
|
98
|
+
const baseUrl = this.blueprint.get<string>('app.api.baseURL', '')
|
|
99
|
+
return isNotEmpty<string>(user.avatar) ? `${baseUrl}/users/${user.id}/avatar` : '/assets/avatar.png'
|
|
100
|
+
}
|
|
101
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import './ErrorLayout.css'
|
|
2
|
+
import { JSX } from 'react'
|
|
3
|
+
import { PageLayout, IPageLayout, StoneOutlet, PageLayoutRenderContext } from '@stone-js/use-react'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Error Layout component.
|
|
7
|
+
*/
|
|
8
|
+
@PageLayout({ name: 'error' })
|
|
9
|
+
export class ErrorLayout implements IPageLayout {
|
|
10
|
+
/**
|
|
11
|
+
* Render the component.
|
|
12
|
+
*
|
|
13
|
+
* @param options - The options for rendering the component.
|
|
14
|
+
* @returns The rendered component.
|
|
15
|
+
*/
|
|
16
|
+
render ({ children }: PageLayoutRenderContext): JSX.Element {
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<header className='mt-64'>
|
|
20
|
+
<div className='container'>
|
|
21
|
+
<p className='pa-24'>
|
|
22
|
+
<img src='/logo.png' className='logo' alt='Stone.js Logo' />
|
|
23
|
+
</p>
|
|
24
|
+
</div>
|
|
25
|
+
</header>
|
|
26
|
+
<main>
|
|
27
|
+
<div className='container'>
|
|
28
|
+
<div className='panel'>
|
|
29
|
+
<StoneOutlet>{children}</StoneOutlet>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</main>
|
|
33
|
+
<footer className='mt-24'>
|
|
34
|
+
<div className='container'>
|
|
35
|
+
<p className='px-24 text-muted'>2025 Stone.js © Noowow Labs</p>
|
|
36
|
+
</div>
|
|
37
|
+
</footer>
|
|
38
|
+
</>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import './SecurityLayout.css'
|
|
2
|
+
import { JSX } from 'react'
|
|
3
|
+
import { PageLayout, IPageLayout, PageLayoutRenderContext, StoneOutlet } from '@stone-js/use-react'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Security Layout component.
|
|
7
|
+
*/
|
|
8
|
+
@PageLayout({ name: 'security' })
|
|
9
|
+
export class SecurityLayout implements IPageLayout {
|
|
10
|
+
/**
|
|
11
|
+
* Render the component.
|
|
12
|
+
*
|
|
13
|
+
* @param options - The options for rendering the component.
|
|
14
|
+
* @returns The rendered component.
|
|
15
|
+
*/
|
|
16
|
+
render ({ children }: PageLayoutRenderContext): JSX.Element {
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<header className='mt-64'>
|
|
20
|
+
<div className='container'>
|
|
21
|
+
<p className='pa-24'>
|
|
22
|
+
<img src='/logo.png' className='logo' alt='Stone.js Logo' />
|
|
23
|
+
</p>
|
|
24
|
+
</div>
|
|
25
|
+
</header>
|
|
26
|
+
<main>
|
|
27
|
+
<div className='container'>
|
|
28
|
+
<StoneOutlet>{children}</StoneOutlet>
|
|
29
|
+
</div>
|
|
30
|
+
</main>
|
|
31
|
+
<footer className='mt-24'>
|
|
32
|
+
<div className='container'>
|
|
33
|
+
<p className='px-24 text-muted'>2025 Stone.js © Noowow Labs</p>
|
|
34
|
+
</div>
|
|
35
|
+
</footer>
|
|
36
|
+
</>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
}
|