From 6f3414e34ac151eae8f3fb7d2d8399e4cdc8e201 Mon Sep 17 00:00:00 2001 From: takecchi Date: Thu, 18 Jan 2024 16:55:05 +0900 Subject: [PATCH] =?UTF-8?q?PagesRouter=E3=81=AB=E7=A7=BB=E8=A1=8C=20(#227)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Issue - Github Issue: #201 ## 変更内容 - AppRouterからPagesRouterに移行しました。 @coderabbitai: ignore --- next.config.js | 43 +++++ package-lock.json | 150 +++++++++++++++++- package.json | 1 + .../home/_components/HomeTimeline.tsx | 2 +- .../invitations/_components/Invitations.tsx | 4 +- src/_app/(menu)/(private)/layout.tsx | 8 + .../[username]/_components/ProfilePage.tsx | 6 +- .../[username]/_components/UserTimeline.tsx | 2 +- .../elements/FollowButton.stories.ts | 0 .../_components/elements/FollowButton.tsx | 2 +- .../_components/elements/HeaderImage.tsx | 0 .../_components/elements/MoreMenu.stories.tsx | 0 .../_components/elements/MoreMenu.tsx | 0 .../_components/elements/UserCount.tsx | 0 .../_components/elements/UserIcon.tsx | 0 .../_components/layouts/EditProfileButton.tsx | 4 +- .../layouts/ProfileCard.stories.ts | 0 .../_components/layouts/ProfileCard.tsx | 10 +- .../layouts/ProfileSettingModal.tsx | 12 +- .../(public)/[username]/_utils/cropImage.ts | 0 .../[username]/posts/_components/PostPage.tsx | 4 +- src/_app/(menu)/README.md | 11 ++ .../(menu)/_components/main/ComingSoon.tsx | 2 +- .../(menu)/_components/main/Loading.tsx | 0 .../_components/main/PrimaryColumn.stories.ts | 2 +- .../(menu)/_components/main/PrimaryColumn.tsx | 2 +- .../(menu)/_components/menu/BottomMenu.tsx | 2 +- .../(menu)/_components/menu/SideMenu.tsx | 8 +- .../_components/menu/elements/LogoLink.tsx | 0 .../MobileBottomMenuItemStyleBase.tsx | 0 .../elements/MobileBottomMenuLinkItem.tsx | 0 .../elements/MobileOpenPostDialogButton.tsx | 4 +- .../menu/elements/SideMenuAccountButton.tsx | 0 .../menu/elements/SideMenuItemStyleBase.tsx | 0 .../menu/elements/SideMenuLinkItem.tsx | 2 +- .../menu/elements/SideMenuPostButton.tsx | 4 +- .../(menu)/_components/timeline/Timeline.tsx | 4 +- .../_components/timeline/TimelinePost.tsx | 4 +- .../_components/timeline/ViewportTrigger.tsx | 0 .../timeline/elements/AvatarIcon.tsx | 0 .../timeline/elements/FavoriteButton.tsx | 0 .../timeline/elements/MomentAgo.tsx | 0 .../timeline/elements/ReplyButton.tsx | 0 .../timeline/elements/RepostButton.tsx | 0 .../timeline/elements/ShareButton.tsx | 0 .../timeline/layouts/Post.stories.ts | 0 .../_components/timeline/layouts/Post.tsx | 12 +- .../_components/timeline/layouts/Showmore.tsx | 0 src/{app => _app}/(menu)/layout.tsx | 6 +- src/_app/(plain)/(guest)/layout.tsx | 8 + .../(guest)/login/_components/LoginForm.tsx | 0 .../(guest)/signup/_components/SignUpForm.tsx | 8 +- .../signup/_components/layouts/StepEmail.tsx | 2 +- .../layouts/StepInvitationCode.tsx | 2 +- .../signup/_components/layouts/StepSignup.tsx | 2 +- .../_components/layouts/StepTemplate.tsx | 0 .../_components/layouts/StepVerifyCode.tsx | 2 +- src/_app/(plain)/(private)/layout.tsx | 8 + .../(private)/logout/_components/Logout.tsx | 2 +- src/_app/(plain)/README.md | 11 ++ .../(plain)/_components/Footer.tsx | 4 +- .../(plain)/_components/LoadingScreen.tsx | 0 src/{app => _app}/README.md | 8 +- src/{app => _app}/_components/NotFound.tsx | 2 +- src/_app/_components/auth/GuestRoute.tsx | 30 ++++ src/_app/_components/auth/PrivateRoute.tsx | 30 ++++ .../_components/button/BackButton.stories.ts | 0 .../_components/button/BackButton.tsx | 0 .../_components/button/Button.tsx | 0 .../button/CapsuleButton.stories.ts | 0 .../_components/button/CapsuleButton.tsx | 0 .../button/CapsuleLoadingButton.tsx | 0 .../_components/button/GitHubLink.tsx | 0 .../_components/button/IconButton.stories.tsx | 0 .../_components/button/IconButton.tsx | 0 .../_components/button/LinkButton.tsx | 0 .../_components/button/LoadingButton.tsx | 0 .../post/ConfirmClosePostDialogDialog.tsx | 0 .../_components/post/PostDialog.tsx | 6 +- .../_components/post/PostForm.tsx | 2 +- .../_components/post/elements/Editor.tsx | 0 .../post/elements/SendPostButton.tsx | 2 +- src/{app => _app}/layout.tsx | 2 - src/app/(menu)/(private)/home/page.tsx | 15 -- src/app/(menu)/(private)/invitations/page.tsx | 10 -- src/app/(menu)/(private)/layout.tsx | 17 -- src/app/(menu)/(private)/messages/page.tsx | 10 -- .../(menu)/(private)/notifications/page.tsx | 15 -- src/app/(menu)/(private)/search/page.tsx | 15 -- src/app/(menu)/(private)/settings/page.tsx | 15 -- .../(public)/[username]/followers/page.tsx | 10 -- .../(public)/[username]/following/page.tsx | 10 -- src/app/(menu)/(public)/[username]/page.tsx | 59 ------- .../[username]/posts/[postId]/page.tsx | 77 --------- src/app/(menu)/README.md | 11 -- src/app/(plain)/(guest)/layout.tsx | 22 --- src/app/(plain)/(private)/layout.tsx | 22 --- src/app/(plain)/(private)/logout/page.tsx | 9 -- src/app/(plain)/README.md | 11 -- src/app/not-found.tsx | 14 -- src/app/robots.ts | 35 ---- src/pages/404.tsx | 15 ++ src/pages/[username]/followers/index.tsx | 16 ++ src/pages/[username]/following/index.tsx | 16 ++ src/pages/[username]/index.tsx | 59 +++++++ src/pages/[username]/posts/[postId]/index.tsx | 86 ++++++++++ src/pages/_app.tsx | 56 +++++++ src/pages/_document.tsx | 31 ++++ src/pages/_meta.tsx | 49 ++++++ .../(public) => pages}/hashtag/.gitkeep | 0 src/pages/home/index.tsx | 27 ++++ .../(guest)/page.tsx => pages/index.tsx} | 15 +- src/pages/invitations/index.tsx | 28 ++++ .../login/page.tsx => pages/login/index.tsx} | 13 +- src/pages/logout/index.tsx | 14 ++ src/pages/messages/index.tsx | 18 +++ src/pages/notifications/index.tsx | 28 ++++ src/pages/robots.txt.ts | 73 +++++++++ src/pages/search/index.tsx | 28 ++++ src/pages/settings/index.tsx | 28 ++++ .../page.tsx => pages/signup/index.tsx} | 13 +- src/styles/globals.css | 13 -- src/types/next.d.ts | 25 +++ 123 files changed, 985 insertions(+), 485 deletions(-) rename src/{app => _app}/(menu)/(private)/home/_components/HomeTimeline.tsx (76%) rename src/{app => _app}/(menu)/(private)/invitations/_components/Invitations.tsx (96%) create mode 100644 src/_app/(menu)/(private)/layout.tsx rename src/{app => _app}/(menu)/(public)/[username]/_components/ProfilePage.tsx (71%) rename src/{app => _app}/(menu)/(public)/[username]/_components/UserTimeline.tsx (82%) rename src/{app => _app}/(menu)/(public)/[username]/_components/elements/FollowButton.stories.ts (100%) rename src/{app => _app}/(menu)/(public)/[username]/_components/elements/FollowButton.tsx (85%) rename src/{app => _app}/(menu)/(public)/[username]/_components/elements/HeaderImage.tsx (100%) rename src/{app => _app}/(menu)/(public)/[username]/_components/elements/MoreMenu.stories.tsx (100%) rename src/{app => _app}/(menu)/(public)/[username]/_components/elements/MoreMenu.tsx (100%) rename src/{app => _app}/(menu)/(public)/[username]/_components/elements/UserCount.tsx (100%) rename src/{app => _app}/(menu)/(public)/[username]/_components/elements/UserIcon.tsx (100%) rename src/{app => _app}/(menu)/(public)/[username]/_components/layouts/EditProfileButton.tsx (80%) rename src/{app => _app}/(menu)/(public)/[username]/_components/layouts/ProfileCard.stories.ts (100%) rename src/{app => _app}/(menu)/(public)/[username]/_components/layouts/ProfileCard.tsx (89%) rename src/{app => _app}/(menu)/(public)/[username]/_components/layouts/ProfileSettingModal.tsx (95%) rename src/{app => _app}/(menu)/(public)/[username]/_utils/cropImage.ts (100%) rename src/{app => _app}/(menu)/(public)/[username]/posts/_components/PostPage.tsx (87%) create mode 100644 src/_app/(menu)/README.md rename src/{app => _app}/(menu)/_components/main/ComingSoon.tsx (96%) rename src/{app => _app}/(menu)/_components/main/Loading.tsx (100%) rename src/{app => _app}/(menu)/_components/main/PrimaryColumn.stories.ts (84%) rename src/{app => _app}/(menu)/_components/main/PrimaryColumn.tsx (96%) rename src/{app => _app}/(menu)/_components/menu/BottomMenu.tsx (94%) rename src/{app => _app}/(menu)/_components/menu/SideMenu.tsx (88%) rename src/{app => _app}/(menu)/_components/menu/elements/LogoLink.tsx (100%) rename src/{app => _app}/(menu)/_components/menu/elements/MobileBottomMenuItemStyleBase.tsx (100%) rename src/{app => _app}/(menu)/_components/menu/elements/MobileBottomMenuLinkItem.tsx (100%) rename src/{app => _app}/(menu)/_components/menu/elements/MobileOpenPostDialogButton.tsx (91%) rename src/{app => _app}/(menu)/_components/menu/elements/SideMenuAccountButton.tsx (100%) rename src/{app => _app}/(menu)/_components/menu/elements/SideMenuItemStyleBase.tsx (100%) rename src/{app => _app}/(menu)/_components/menu/elements/SideMenuLinkItem.tsx (93%) rename src/{app => _app}/(menu)/_components/menu/elements/SideMenuPostButton.tsx (88%) rename src/{app => _app}/(menu)/_components/timeline/Timeline.tsx (94%) rename src/{app => _app}/(menu)/_components/timeline/TimelinePost.tsx (89%) rename src/{app => _app}/(menu)/_components/timeline/ViewportTrigger.tsx (100%) rename src/{app => _app}/(menu)/_components/timeline/elements/AvatarIcon.tsx (100%) rename src/{app => _app}/(menu)/_components/timeline/elements/FavoriteButton.tsx (100%) rename src/{app => _app}/(menu)/_components/timeline/elements/MomentAgo.tsx (100%) rename src/{app => _app}/(menu)/_components/timeline/elements/ReplyButton.tsx (100%) rename src/{app => _app}/(menu)/_components/timeline/elements/RepostButton.tsx (100%) rename src/{app => _app}/(menu)/_components/timeline/elements/ShareButton.tsx (100%) rename src/{app => _app}/(menu)/_components/timeline/layouts/Post.stories.ts (100%) rename src/{app => _app}/(menu)/_components/timeline/layouts/Post.tsx (90%) rename src/{app => _app}/(menu)/_components/timeline/layouts/Showmore.tsx (100%) rename src/{app => _app}/(menu)/layout.tsx (80%) create mode 100644 src/_app/(plain)/(guest)/layout.tsx rename src/{app => _app}/(plain)/(guest)/login/_components/LoginForm.tsx (100%) rename src/{app => _app}/(plain)/(guest)/signup/_components/SignUpForm.tsx (84%) rename src/{app => _app}/(plain)/(guest)/signup/_components/layouts/StepEmail.tsx (93%) rename src/{app => _app}/(plain)/(guest)/signup/_components/layouts/StepInvitationCode.tsx (92%) rename src/{app => _app}/(plain)/(guest)/signup/_components/layouts/StepSignup.tsx (96%) rename src/{app => _app}/(plain)/(guest)/signup/_components/layouts/StepTemplate.tsx (100%) rename src/{app => _app}/(plain)/(guest)/signup/_components/layouts/StepVerifyCode.tsx (92%) create mode 100644 src/_app/(plain)/(private)/layout.tsx rename src/{app => _app}/(plain)/(private)/logout/_components/Logout.tsx (94%) create mode 100644 src/_app/(plain)/README.md rename src/{app => _app}/(plain)/_components/Footer.tsx (92%) rename src/{app => _app}/(plain)/_components/LoadingScreen.tsx (100%) rename src/{app => _app}/README.md (69%) rename src/{app => _app}/_components/NotFound.tsx (95%) create mode 100644 src/_app/_components/auth/GuestRoute.tsx create mode 100644 src/_app/_components/auth/PrivateRoute.tsx rename src/{app => _app}/_components/button/BackButton.stories.ts (100%) rename src/{app => _app}/_components/button/BackButton.tsx (100%) rename src/{app => _app}/_components/button/Button.tsx (100%) rename src/{app => _app}/_components/button/CapsuleButton.stories.ts (100%) rename src/{app => _app}/_components/button/CapsuleButton.tsx (100%) rename src/{app => _app}/_components/button/CapsuleLoadingButton.tsx (100%) rename src/{app => _app}/_components/button/GitHubLink.tsx (100%) rename src/{app => _app}/_components/button/IconButton.stories.tsx (100%) rename src/{app => _app}/_components/button/IconButton.tsx (100%) rename src/{app => _app}/_components/button/LinkButton.tsx (100%) rename src/{app => _app}/_components/button/LoadingButton.tsx (100%) rename src/{app => _app}/_components/post/ConfirmClosePostDialogDialog.tsx (100%) rename src/{app => _app}/_components/post/PostDialog.tsx (93%) rename src/{app => _app}/_components/post/PostForm.tsx (95%) rename src/{app => _app}/_components/post/elements/Editor.tsx (100%) rename src/{app => _app}/_components/post/elements/SendPostButton.tsx (93%) rename src/{app => _app}/layout.tsx (98%) delete mode 100644 src/app/(menu)/(private)/home/page.tsx delete mode 100644 src/app/(menu)/(private)/invitations/page.tsx delete mode 100644 src/app/(menu)/(private)/layout.tsx delete mode 100644 src/app/(menu)/(private)/messages/page.tsx delete mode 100644 src/app/(menu)/(private)/notifications/page.tsx delete mode 100644 src/app/(menu)/(private)/search/page.tsx delete mode 100644 src/app/(menu)/(private)/settings/page.tsx delete mode 100644 src/app/(menu)/(public)/[username]/followers/page.tsx delete mode 100644 src/app/(menu)/(public)/[username]/following/page.tsx delete mode 100644 src/app/(menu)/(public)/[username]/page.tsx delete mode 100644 src/app/(menu)/(public)/[username]/posts/[postId]/page.tsx delete mode 100644 src/app/(menu)/README.md delete mode 100644 src/app/(plain)/(guest)/layout.tsx delete mode 100644 src/app/(plain)/(private)/layout.tsx delete mode 100644 src/app/(plain)/(private)/logout/page.tsx delete mode 100644 src/app/(plain)/README.md delete mode 100644 src/app/not-found.tsx delete mode 100644 src/app/robots.ts create mode 100644 src/pages/404.tsx create mode 100644 src/pages/[username]/followers/index.tsx create mode 100644 src/pages/[username]/following/index.tsx create mode 100644 src/pages/[username]/index.tsx create mode 100644 src/pages/[username]/posts/[postId]/index.tsx create mode 100644 src/pages/_app.tsx create mode 100644 src/pages/_document.tsx create mode 100644 src/pages/_meta.tsx rename src/{app/(menu)/(public) => pages}/hashtag/.gitkeep (100%) create mode 100644 src/pages/home/index.tsx rename src/{app/(plain)/(guest)/page.tsx => pages/index.tsx} (85%) create mode 100644 src/pages/invitations/index.tsx rename src/{app/(plain)/(guest)/login/page.tsx => pages/login/index.tsx} (89%) create mode 100644 src/pages/logout/index.tsx create mode 100644 src/pages/messages/index.tsx create mode 100644 src/pages/notifications/index.tsx create mode 100644 src/pages/robots.txt.ts create mode 100644 src/pages/search/index.tsx create mode 100644 src/pages/settings/index.tsx rename src/{app/(plain)/(guest)/signup/page.tsx => pages/signup/index.tsx} (87%) delete mode 100644 src/styles/globals.css create mode 100644 src/types/next.d.ts diff --git a/next.config.js b/next.config.js index 5fa98156..d1a40b7a 100644 --- a/next.config.js +++ b/next.config.js @@ -18,6 +18,49 @@ const nextConfig = { transform: '@mui/lab/{{member}}', }, }, + headers: async () => { + return [ + { + source: '/(.*)', + headers: [ + { + key: 'Cache-Control', + value: 's-maxage=86400, stale-while-revalidate=86400', + }, + { + key: 'X-DEBUG', + value: 'all', + }, + ], + }, + { + source: '/:username', + headers: [ + { + key: 'Cache-Control', + value: 's-maxage=86400, stale-while-revalidate=86400', + }, + { + key: 'X-DEBUG', + value: 'username', + }, + ], + }, + { + source: '/:username/posts/:postId', + headers: [ + { + key: 'Cache-Control', + value: 's-maxage=86400, stale-while-revalidate=86400', + }, + { + key: 'X-DEBUG', + value: 'post', + }, + ], + }, + ]; + }, }; module.exports = withPWA(nextConfig); diff --git a/package-lock.json b/package-lock.json index c8ce0a0b..573ce400 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@ducanh2912/next-pwa": "10.2.2", "@emotion/cache": "11.11.0", "@emotion/react": "11.11.3", + "@emotion/server": "11.11.0", "@emotion/styled": "11.11.0", "@mui/icons-material": "5.15.5", "@mui/lab": "5.0.0-alpha.161", @@ -4961,6 +4962,25 @@ "csstype": "^3.0.2" } }, + "node_modules/@emotion/server": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/server/-/server-11.11.0.tgz", + "integrity": "sha512-6q89fj2z8VBTx9w93kJ5n51hsmtYuFPtZgnc1L8VzRx9ti4EU6EyvF6Nn1H1x3vcCQCF7u2dB2lY4AYJwUW4PA==", + "dependencies": { + "@emotion/utils": "^1.2.1", + "html-tokenize": "^2.0.0", + "multipipe": "^1.0.2", + "through": "^2.3.8" + }, + "peerDependencies": { + "@emotion/css": "^11.0.0-rc.0" + }, + "peerDependenciesMeta": { + "@emotion/css": { + "optional": true + } + } + }, "node_modules/@emotion/sheet": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", @@ -17053,8 +17073,7 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cosmiconfig": { "version": "8.3.6", @@ -18138,6 +18157,46 @@ "node": ">=4" } }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -20985,6 +21044,72 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/html-tokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-tokenize/-/html-tokenize-2.0.1.tgz", + "integrity": "sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w==", + "dependencies": { + "buffer-from": "~0.1.1", + "inherits": "~2.0.1", + "minimist": "~1.2.5", + "readable-stream": "~1.0.27-1", + "through2": "~0.4.1" + }, + "bin": { + "html-tokenize": "bin/cmd.js" + } + }, + "node_modules/html-tokenize/node_modules/buffer-from": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", + "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==" + }, + "node_modules/html-tokenize/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/html-tokenize/node_modules/object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==" + }, + "node_modules/html-tokenize/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/html-tokenize/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/html-tokenize/node_modules/through2": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", + "integrity": "sha512-45Llu+EwHKtAZYTPPVn3XZHBgakWMN3rokhEv5hu596XP+cNgplMg+Gj+1nmAvj+L0K7+N49zBKx5rah5u0QIQ==", + "dependencies": { + "readable-stream": "~1.0.17", + "xtend": "~2.1.1" + } + }, + "node_modules/html-tokenize/node_modules/xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==", + "dependencies": { + "object-keys": "~0.4.0" + }, + "engines": { + "node": ">=0.4" + } + }, "node_modules/html-webpack-plugin": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", @@ -24994,7 +25119,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -25189,6 +25313,15 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/multipipe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-1.0.2.tgz", + "integrity": "sha512-6uiC9OvY71vzSGX8lZvSqscE7ft9nPupJ8fMjrCNRAUy2LREUW42UL+V/NTrogr6rFgRydUrCX4ZitfpSNkSCQ==", + "dependencies": { + "duplexer2": "^0.1.2", + "object-assign": "^4.1.0" + } + }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -26970,8 +27103,7 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/process-on-spawn": { "version": "1.0.0", @@ -31106,6 +31238,11 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, "node_modules/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -31823,8 +31960,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utila": { "version": "0.4.0", diff --git a/package.json b/package.json index ea70e39f..3d5c54d5 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@ducanh2912/next-pwa": "10.2.2", "@emotion/cache": "11.11.0", "@emotion/react": "11.11.3", + "@emotion/server": "11.11.0", "@emotion/styled": "11.11.0", "@mui/icons-material": "5.15.5", "@mui/lab": "5.0.0-alpha.161", diff --git a/src/app/(menu)/(private)/home/_components/HomeTimeline.tsx b/src/_app/(menu)/(private)/home/_components/HomeTimeline.tsx similarity index 76% rename from src/app/(menu)/(private)/home/_components/HomeTimeline.tsx rename to src/_app/(menu)/(private)/home/_components/HomeTimeline.tsx index 067db14e..8d2028e6 100644 --- a/src/app/(menu)/(private)/home/_components/HomeTimeline.tsx +++ b/src/_app/(menu)/(private)/home/_components/HomeTimeline.tsx @@ -1,7 +1,7 @@ 'use client'; import { useHomeTimeline } from '@/swr/client/timeline'; -import Timeline from '@/app/(menu)/_components/timeline/Timeline'; +import Timeline from '@/_app/(menu)/_components/timeline/Timeline'; /** * ホームタイムライン diff --git a/src/app/(menu)/(private)/invitations/_components/Invitations.tsx b/src/_app/(menu)/(private)/invitations/_components/Invitations.tsx similarity index 96% rename from src/app/(menu)/(private)/invitations/_components/Invitations.tsx rename to src/_app/(menu)/(private)/invitations/_components/Invitations.tsx index 6fb00549..cb808db8 100644 --- a/src/app/(menu)/(private)/invitations/_components/Invitations.tsx +++ b/src/_app/(menu)/(private)/invitations/_components/Invitations.tsx @@ -12,9 +12,9 @@ import { import { useInvitationCreate, useInvitations } from '@/swr/client/invitations'; import { useEffect, useState } from 'react'; import { Invitation } from '@cuculus/cuculus-api/dist/models/Invitation'; -import Loading from '@/app/(menu)/_components/main/Loading'; +import Loading from '@/_app/(menu)/_components/main/Loading'; import { ContentCopy } from '@mui/icons-material'; -import LoadingButton from '@/app/_components/button/LoadingButton'; +import LoadingButton from '@/_app/_components/button/LoadingButton'; const Root = styled('div')` display: flex; diff --git a/src/_app/(menu)/(private)/layout.tsx b/src/_app/(menu)/(private)/layout.tsx new file mode 100644 index 00000000..786af722 --- /dev/null +++ b/src/_app/(menu)/(private)/layout.tsx @@ -0,0 +1,8 @@ +'use client'; + +import { ReactNode } from 'react'; +import PrivateRoute from '@/_app/_components/auth/PrivateRoute'; + +export default function Layout({ children }: { children: ReactNode }) { + return {children}; +} diff --git a/src/app/(menu)/(public)/[username]/_components/ProfilePage.tsx b/src/_app/(menu)/(public)/[username]/_components/ProfilePage.tsx similarity index 71% rename from src/app/(menu)/(public)/[username]/_components/ProfilePage.tsx rename to src/_app/(menu)/(public)/[username]/_components/ProfilePage.tsx index 241f056f..616e77c0 100644 --- a/src/app/(menu)/(public)/[username]/_components/ProfilePage.tsx +++ b/src/_app/(menu)/(public)/[username]/_components/ProfilePage.tsx @@ -1,9 +1,9 @@ 'use client'; -import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn'; -import ProfileCard from '@/app/(menu)/(public)/[username]/_components/layouts/ProfileCard'; +import PrimaryColumn from '@/_app/(menu)/_components/main/PrimaryColumn'; +import ProfileCard from '@/_app/(menu)/(public)/[username]/_components/layouts/ProfileCard'; import { useUser } from '@/swr/client/user'; -import UserTimeline from '@/app/(menu)/(public)/[username]/_components/UserTimeline'; +import UserTimeline from '@/_app/(menu)/(public)/[username]/_components/UserTimeline'; import { UserWithFollows } from '@cuculus/cuculus-api'; import { useAuth } from '@/swr/client/auth'; diff --git a/src/app/(menu)/(public)/[username]/_components/UserTimeline.tsx b/src/_app/(menu)/(public)/[username]/_components/UserTimeline.tsx similarity index 82% rename from src/app/(menu)/(public)/[username]/_components/UserTimeline.tsx rename to src/_app/(menu)/(public)/[username]/_components/UserTimeline.tsx index 8dd14d3d..1253ab80 100644 --- a/src/app/(menu)/(public)/[username]/_components/UserTimeline.tsx +++ b/src/_app/(menu)/(public)/[username]/_components/UserTimeline.tsx @@ -1,7 +1,7 @@ 'use client'; import { useUserPosts } from '@/swr/client/user'; -import Timeline from '@/app/(menu)/_components/timeline/Timeline'; +import Timeline from '@/_app/(menu)/_components/timeline/Timeline'; import { UserWithFollows } from '@cuculus/cuculus-api'; /** diff --git a/src/app/(menu)/(public)/[username]/_components/elements/FollowButton.stories.ts b/src/_app/(menu)/(public)/[username]/_components/elements/FollowButton.stories.ts similarity index 100% rename from src/app/(menu)/(public)/[username]/_components/elements/FollowButton.stories.ts rename to src/_app/(menu)/(public)/[username]/_components/elements/FollowButton.stories.ts diff --git a/src/app/(menu)/(public)/[username]/_components/elements/FollowButton.tsx b/src/_app/(menu)/(public)/[username]/_components/elements/FollowButton.tsx similarity index 85% rename from src/app/(menu)/(public)/[username]/_components/elements/FollowButton.tsx rename to src/_app/(menu)/(public)/[username]/_components/elements/FollowButton.tsx index 9f9217dd..c6564c09 100644 --- a/src/app/(menu)/(public)/[username]/_components/elements/FollowButton.tsx +++ b/src/_app/(menu)/(public)/[username]/_components/elements/FollowButton.tsx @@ -1,6 +1,6 @@ 'use client'; -import CapsuleButton from '@/app/_components/button/CapsuleButton'; +import CapsuleButton from '@/_app/_components/button/CapsuleButton'; type Props = { userId: number; diff --git a/src/app/(menu)/(public)/[username]/_components/elements/HeaderImage.tsx b/src/_app/(menu)/(public)/[username]/_components/elements/HeaderImage.tsx similarity index 100% rename from src/app/(menu)/(public)/[username]/_components/elements/HeaderImage.tsx rename to src/_app/(menu)/(public)/[username]/_components/elements/HeaderImage.tsx diff --git a/src/app/(menu)/(public)/[username]/_components/elements/MoreMenu.stories.tsx b/src/_app/(menu)/(public)/[username]/_components/elements/MoreMenu.stories.tsx similarity index 100% rename from src/app/(menu)/(public)/[username]/_components/elements/MoreMenu.stories.tsx rename to src/_app/(menu)/(public)/[username]/_components/elements/MoreMenu.stories.tsx diff --git a/src/app/(menu)/(public)/[username]/_components/elements/MoreMenu.tsx b/src/_app/(menu)/(public)/[username]/_components/elements/MoreMenu.tsx similarity index 100% rename from src/app/(menu)/(public)/[username]/_components/elements/MoreMenu.tsx rename to src/_app/(menu)/(public)/[username]/_components/elements/MoreMenu.tsx diff --git a/src/app/(menu)/(public)/[username]/_components/elements/UserCount.tsx b/src/_app/(menu)/(public)/[username]/_components/elements/UserCount.tsx similarity index 100% rename from src/app/(menu)/(public)/[username]/_components/elements/UserCount.tsx rename to src/_app/(menu)/(public)/[username]/_components/elements/UserCount.tsx diff --git a/src/app/(menu)/(public)/[username]/_components/elements/UserIcon.tsx b/src/_app/(menu)/(public)/[username]/_components/elements/UserIcon.tsx similarity index 100% rename from src/app/(menu)/(public)/[username]/_components/elements/UserIcon.tsx rename to src/_app/(menu)/(public)/[username]/_components/elements/UserIcon.tsx diff --git a/src/app/(menu)/(public)/[username]/_components/layouts/EditProfileButton.tsx b/src/_app/(menu)/(public)/[username]/_components/layouts/EditProfileButton.tsx similarity index 80% rename from src/app/(menu)/(public)/[username]/_components/layouts/EditProfileButton.tsx rename to src/_app/(menu)/(public)/[username]/_components/layouts/EditProfileButton.tsx index 73a77844..d768927d 100644 --- a/src/app/(menu)/(public)/[username]/_components/layouts/EditProfileButton.tsx +++ b/src/_app/(menu)/(public)/[username]/_components/layouts/EditProfileButton.tsx @@ -1,7 +1,7 @@ 'use client'; -import CapsuleButton from '@/app/_components/button/CapsuleButton'; -import ProfileSettingModal from '@/app/(menu)/(public)/[username]/_components/layouts/ProfileSettingModal'; +import CapsuleButton from '@/_app/_components/button/CapsuleButton'; +import ProfileSettingModal from '@/_app/(menu)/(public)/[username]/_components/layouts/ProfileSettingModal'; import { useState } from 'react'; import { useProfile } from '@/swr/client/auth'; diff --git a/src/app/(menu)/(public)/[username]/_components/layouts/ProfileCard.stories.ts b/src/_app/(menu)/(public)/[username]/_components/layouts/ProfileCard.stories.ts similarity index 100% rename from src/app/(menu)/(public)/[username]/_components/layouts/ProfileCard.stories.ts rename to src/_app/(menu)/(public)/[username]/_components/layouts/ProfileCard.stories.ts diff --git a/src/app/(menu)/(public)/[username]/_components/layouts/ProfileCard.tsx b/src/_app/(menu)/(public)/[username]/_components/layouts/ProfileCard.tsx similarity index 89% rename from src/app/(menu)/(public)/[username]/_components/layouts/ProfileCard.tsx rename to src/_app/(menu)/(public)/[username]/_components/layouts/ProfileCard.tsx index 203c8d8a..08681e08 100644 --- a/src/app/(menu)/(public)/[username]/_components/layouts/ProfileCard.tsx +++ b/src/_app/(menu)/(public)/[username]/_components/layouts/ProfileCard.tsx @@ -1,13 +1,13 @@ 'use client'; import { Box, Typography, styled } from '@mui/material'; -import { FollowButton } from '@/app/(menu)/(public)/[username]/_components/elements/FollowButton'; -import UserCount from '@/app/(menu)/(public)/[username]/_components/elements/UserCount'; +import { FollowButton } from '@/_app/(menu)/(public)/[username]/_components/elements/FollowButton'; +import UserCount from '@/_app/(menu)/(public)/[username]/_components/elements/UserCount'; import { usePathname } from 'next/navigation'; -import HeaderImage from '@/app/(menu)/(public)/[username]/_components/elements/HeaderImage'; -import UserIcon from '@/app/(menu)/(public)/[username]/_components/elements/UserIcon'; +import HeaderImage from '@/_app/(menu)/(public)/[username]/_components/elements/HeaderImage'; +import UserIcon from '@/_app/(menu)/(public)/[username]/_components/elements/UserIcon'; import { UserWithFollows } from '@cuculus/cuculus-api'; -import { EditProfileButton } from '@/app/(menu)/(public)/[username]/_components/layouts/EditProfileButton'; +import { EditProfileButton } from '@/_app/(menu)/(public)/[username]/_components/layouts/EditProfileButton'; const UnselectableCard = styled('div')` border-bottom: 1px solid ${({ theme }) => theme.palette.grey[100]}; diff --git a/src/app/(menu)/(public)/[username]/_components/layouts/ProfileSettingModal.tsx b/src/_app/(menu)/(public)/[username]/_components/layouts/ProfileSettingModal.tsx similarity index 95% rename from src/app/(menu)/(public)/[username]/_components/layouts/ProfileSettingModal.tsx rename to src/_app/(menu)/(public)/[username]/_components/layouts/ProfileSettingModal.tsx index 4a9c1db6..dbd55978 100644 --- a/src/app/(menu)/(public)/[username]/_components/layouts/ProfileSettingModal.tsx +++ b/src/_app/(menu)/(public)/[username]/_components/layouts/ProfileSettingModal.tsx @@ -17,14 +17,14 @@ import { ZoomIn, ZoomOut, } from '@mui/icons-material'; -import { IconButton } from '@/app/_components/button/IconButton'; -import HeaderImage from '@/app/(menu)/(public)/[username]/_components/elements/HeaderImage'; -import UserIcon from '@/app/(menu)/(public)/[username]/_components/elements/UserIcon'; +import { IconButton } from '@/_app/_components/button/IconButton'; +import HeaderImage from '@/_app/(menu)/(public)/[username]/_components/elements/HeaderImage'; +import UserIcon from '@/_app/(menu)/(public)/[username]/_components/elements/UserIcon'; import Cropper, { Area, Point } from 'react-easy-crop'; -import CapsuleButton from '@/app/_components/button/CapsuleButton'; -import { getCroppedImg } from '@/app/(menu)/(public)/[username]/_utils/cropImage'; +import CapsuleButton from '@/_app/_components/button/CapsuleButton'; +import { getCroppedImg } from '@/_app/(menu)/(public)/[username]/_utils/cropImage'; import { useProfileMutation } from '@/swr/client/profile'; -import CapsuleLoadingButton from '@/app/_components/button/CapsuleLoadingButton'; +import CapsuleLoadingButton from '@/_app/_components/button/CapsuleLoadingButton'; const HEADER_HEIGHT = '50px'; const SLIDER_HEIGHT = '50px'; diff --git a/src/app/(menu)/(public)/[username]/_utils/cropImage.ts b/src/_app/(menu)/(public)/[username]/_utils/cropImage.ts similarity index 100% rename from src/app/(menu)/(public)/[username]/_utils/cropImage.ts rename to src/_app/(menu)/(public)/[username]/_utils/cropImage.ts diff --git a/src/app/(menu)/(public)/[username]/posts/_components/PostPage.tsx b/src/_app/(menu)/(public)/[username]/posts/_components/PostPage.tsx similarity index 87% rename from src/app/(menu)/(public)/[username]/posts/_components/PostPage.tsx rename to src/_app/(menu)/(public)/[username]/posts/_components/PostPage.tsx index 7cae8e06..32f7dc53 100644 --- a/src/app/(menu)/(public)/[username]/posts/_components/PostPage.tsx +++ b/src/_app/(menu)/(public)/[username]/posts/_components/PostPage.tsx @@ -1,9 +1,9 @@ 'use client'; -import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn'; +import PrimaryColumn from '@/_app/(menu)/_components/main/PrimaryColumn'; import { UserPost } from '@cuculus/cuculus-api'; import { usePost } from '@/swr/client/post'; -import Post from '@/app/(menu)/_components/timeline/layouts/Post'; +import Post from '@/_app/(menu)/_components/timeline/layouts/Post'; type Props = { postId: string; diff --git a/src/_app/(menu)/README.md b/src/_app/(menu)/README.md new file mode 100644 index 00000000..7dc5a41f --- /dev/null +++ b/src/_app/(menu)/README.md @@ -0,0 +1,11 @@ +# [@/_app/(menu)](.) +メニューを持つ画面グループです。 + +## [@/_app/(menu)/(private)](./(private)) +ログインが必須のページ + +## [@/_app/(menu)/(public)](./(public)) +ログインしていても、してなくても良いページ + +## [@/_app/(menu)/_components](./_components) +`@/_app/(menu)`配下で使用するコンポーネント置き場です。 diff --git a/src/app/(menu)/_components/main/ComingSoon.tsx b/src/_app/(menu)/_components/main/ComingSoon.tsx similarity index 96% rename from src/app/(menu)/_components/main/ComingSoon.tsx rename to src/_app/(menu)/_components/main/ComingSoon.tsx index 202e506b..8eb6dd38 100644 --- a/src/app/(menu)/_components/main/ComingSoon.tsx +++ b/src/_app/(menu)/_components/main/ComingSoon.tsx @@ -1,7 +1,7 @@ 'use client'; import { styled } from '@mui/material'; -import LinkButton from '@/app/_components/button/LinkButton'; +import LinkButton from '@/_app/_components/button/LinkButton'; import { MuseoModerno } from 'next/font/google'; const museoModerno = MuseoModerno({ subsets: ['latin'], weight: ['700'] }); diff --git a/src/app/(menu)/_components/main/Loading.tsx b/src/_app/(menu)/_components/main/Loading.tsx similarity index 100% rename from src/app/(menu)/_components/main/Loading.tsx rename to src/_app/(menu)/_components/main/Loading.tsx diff --git a/src/app/(menu)/_components/main/PrimaryColumn.stories.ts b/src/_app/(menu)/_components/main/PrimaryColumn.stories.ts similarity index 84% rename from src/app/(menu)/_components/main/PrimaryColumn.stories.ts rename to src/_app/(menu)/_components/main/PrimaryColumn.stories.ts index 63e236ff..b337b827 100644 --- a/src/app/(menu)/_components/main/PrimaryColumn.stories.ts +++ b/src/_app/(menu)/_components/main/PrimaryColumn.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; -import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn'; +import PrimaryColumn from '@/_app/(menu)/_components/main/PrimaryColumn'; const meta: Meta = { component: PrimaryColumn, diff --git a/src/app/(menu)/_components/main/PrimaryColumn.tsx b/src/_app/(menu)/_components/main/PrimaryColumn.tsx similarity index 96% rename from src/app/(menu)/_components/main/PrimaryColumn.tsx rename to src/_app/(menu)/_components/main/PrimaryColumn.tsx index 964cd956..ee461dcc 100644 --- a/src/app/(menu)/_components/main/PrimaryColumn.tsx +++ b/src/_app/(menu)/_components/main/PrimaryColumn.tsx @@ -2,7 +2,7 @@ import { styled } from '@mui/material'; import { ReactNode } from 'react'; -import BackButton from '@/app/_components/button/BackButton'; +import BackButton from '@/_app/_components/button/BackButton'; const Main = styled('main')` display: flex; diff --git a/src/app/(menu)/_components/menu/BottomMenu.tsx b/src/_app/(menu)/_components/menu/BottomMenu.tsx similarity index 94% rename from src/app/(menu)/_components/menu/BottomMenu.tsx rename to src/_app/(menu)/_components/menu/BottomMenu.tsx index f6e71931..5ae5acff 100644 --- a/src/app/(menu)/_components/menu/BottomMenu.tsx +++ b/src/_app/(menu)/_components/menu/BottomMenu.tsx @@ -1,6 +1,6 @@ 'use client'; -import MobileBottomMenuLinkItem from '@/app/(menu)/_components/menu/elements/MobileBottomMenuLinkItem'; +import MobileBottomMenuLinkItem from '@/_app/(menu)/_components/menu/elements/MobileBottomMenuLinkItem'; import { useProfile } from '@/swr/client/auth'; import { Home, diff --git a/src/app/(menu)/_components/menu/SideMenu.tsx b/src/_app/(menu)/_components/menu/SideMenu.tsx similarity index 88% rename from src/app/(menu)/_components/menu/SideMenu.tsx rename to src/_app/(menu)/_components/menu/SideMenu.tsx index 6a908d1f..c84ef183 100644 --- a/src/app/(menu)/_components/menu/SideMenu.tsx +++ b/src/_app/(menu)/_components/menu/SideMenu.tsx @@ -13,11 +13,11 @@ import { Settings, SettingsOutlined, } from '@mui/icons-material'; -import SideMenuAccountButton from '@/app/(menu)/_components/menu/elements/SideMenuAccountButton'; -import SideMenuPostButton from '@/app/(menu)/_components/menu/elements/SideMenuPostButton'; -import SideMenuLinkItem from '@/app/(menu)/_components/menu/elements/SideMenuLinkItem'; +import SideMenuAccountButton from '@/_app/(menu)/_components/menu/elements/SideMenuAccountButton'; +import SideMenuPostButton from '@/_app/(menu)/_components/menu/elements/SideMenuPostButton'; +import SideMenuLinkItem from '@/_app/(menu)/_components/menu/elements/SideMenuLinkItem'; import { useProfile } from '@/swr/client/auth'; -import LogoLink from '@/app/(menu)/_components/menu/elements/LogoLink'; +import LogoLink from '@/_app/(menu)/_components/menu/elements/LogoLink'; const Root = styled('div')` // Desktop diff --git a/src/app/(menu)/_components/menu/elements/LogoLink.tsx b/src/_app/(menu)/_components/menu/elements/LogoLink.tsx similarity index 100% rename from src/app/(menu)/_components/menu/elements/LogoLink.tsx rename to src/_app/(menu)/_components/menu/elements/LogoLink.tsx diff --git a/src/app/(menu)/_components/menu/elements/MobileBottomMenuItemStyleBase.tsx b/src/_app/(menu)/_components/menu/elements/MobileBottomMenuItemStyleBase.tsx similarity index 100% rename from src/app/(menu)/_components/menu/elements/MobileBottomMenuItemStyleBase.tsx rename to src/_app/(menu)/_components/menu/elements/MobileBottomMenuItemStyleBase.tsx diff --git a/src/app/(menu)/_components/menu/elements/MobileBottomMenuLinkItem.tsx b/src/_app/(menu)/_components/menu/elements/MobileBottomMenuLinkItem.tsx similarity index 100% rename from src/app/(menu)/_components/menu/elements/MobileBottomMenuLinkItem.tsx rename to src/_app/(menu)/_components/menu/elements/MobileBottomMenuLinkItem.tsx diff --git a/src/app/(menu)/_components/menu/elements/MobileOpenPostDialogButton.tsx b/src/_app/(menu)/_components/menu/elements/MobileOpenPostDialogButton.tsx similarity index 91% rename from src/app/(menu)/_components/menu/elements/MobileOpenPostDialogButton.tsx rename to src/_app/(menu)/_components/menu/elements/MobileOpenPostDialogButton.tsx index aaca5997..255f7367 100644 --- a/src/app/(menu)/_components/menu/elements/MobileOpenPostDialogButton.tsx +++ b/src/_app/(menu)/_components/menu/elements/MobileOpenPostDialogButton.tsx @@ -1,7 +1,7 @@ 'use client'; -import { IconButton } from '@/app/_components/button/IconButton'; -import PostDialog from '@/app/_components/post/PostDialog'; +import { IconButton } from '@/_app/_components/button/IconButton'; +import PostDialog from '@/_app/_components/post/PostDialog'; import { useAuth } from '@/swr/client/auth'; import { Send } from '@mui/icons-material'; import { styled } from '@mui/material'; diff --git a/src/app/(menu)/_components/menu/elements/SideMenuAccountButton.tsx b/src/_app/(menu)/_components/menu/elements/SideMenuAccountButton.tsx similarity index 100% rename from src/app/(menu)/_components/menu/elements/SideMenuAccountButton.tsx rename to src/_app/(menu)/_components/menu/elements/SideMenuAccountButton.tsx diff --git a/src/app/(menu)/_components/menu/elements/SideMenuItemStyleBase.tsx b/src/_app/(menu)/_components/menu/elements/SideMenuItemStyleBase.tsx similarity index 100% rename from src/app/(menu)/_components/menu/elements/SideMenuItemStyleBase.tsx rename to src/_app/(menu)/_components/menu/elements/SideMenuItemStyleBase.tsx diff --git a/src/app/(menu)/_components/menu/elements/SideMenuLinkItem.tsx b/src/_app/(menu)/_components/menu/elements/SideMenuLinkItem.tsx similarity index 93% rename from src/app/(menu)/_components/menu/elements/SideMenuLinkItem.tsx rename to src/_app/(menu)/_components/menu/elements/SideMenuLinkItem.tsx index 7612662f..ad438c75 100644 --- a/src/app/(menu)/_components/menu/elements/SideMenuLinkItem.tsx +++ b/src/_app/(menu)/_components/menu/elements/SideMenuLinkItem.tsx @@ -1,6 +1,6 @@ 'use client'; -import SideMenuItemStyleBase from '@/app/(menu)/_components/menu/elements/SideMenuItemStyleBase'; +import SideMenuItemStyleBase from '@/_app/(menu)/_components/menu/elements/SideMenuItemStyleBase'; import { Box, styled } from '@mui/material'; import NextLink from 'next/link'; import { usePathname } from 'next/navigation'; diff --git a/src/app/(menu)/_components/menu/elements/SideMenuPostButton.tsx b/src/_app/(menu)/_components/menu/elements/SideMenuPostButton.tsx similarity index 88% rename from src/app/(menu)/_components/menu/elements/SideMenuPostButton.tsx rename to src/_app/(menu)/_components/menu/elements/SideMenuPostButton.tsx index 45337df8..f5370c13 100644 --- a/src/app/(menu)/_components/menu/elements/SideMenuPostButton.tsx +++ b/src/_app/(menu)/_components/menu/elements/SideMenuPostButton.tsx @@ -1,7 +1,7 @@ 'use client'; -import PostDialog from '@/app/_components/post/PostDialog'; -import SideMenuItemStyleBase from '@/app/(menu)/_components/menu/elements/SideMenuItemStyleBase'; +import PostDialog from '@/_app/_components/post/PostDialog'; +import SideMenuItemStyleBase from '@/_app/(menu)/_components/menu/elements/SideMenuItemStyleBase'; import { Send } from '@mui/icons-material'; import { Box, styled } from '@mui/material'; import { useState } from 'react'; diff --git a/src/app/(menu)/_components/timeline/Timeline.tsx b/src/_app/(menu)/_components/timeline/Timeline.tsx similarity index 94% rename from src/app/(menu)/_components/timeline/Timeline.tsx rename to src/_app/(menu)/_components/timeline/Timeline.tsx index 3520fa4f..e975972a 100644 --- a/src/app/(menu)/_components/timeline/Timeline.tsx +++ b/src/_app/(menu)/_components/timeline/Timeline.tsx @@ -1,11 +1,11 @@ 'use client'; -import TimelinePost from '@/app/(menu)/_components/timeline/TimelinePost'; +import TimelinePost from '@/_app/(menu)/_components/timeline/TimelinePost'; import { serializeGap } from '@/libs/swr/timeline/utils'; import { CircularProgress } from '@mui/material'; import { UserPost } from '@cuculus/cuculus-api'; import { SWRTimelineResponse, TimelineData } from '@/libs/swr/timeline/types'; -import Showmore from '@/app/(menu)/_components/timeline/layouts/Showmore'; +import Showmore from '@/_app/(menu)/_components/timeline/layouts/Showmore'; import { WindowVirtualizer } from 'virtua'; // 投稿の件数をカウントする diff --git a/src/app/(menu)/_components/timeline/TimelinePost.tsx b/src/_app/(menu)/_components/timeline/TimelinePost.tsx similarity index 89% rename from src/app/(menu)/_components/timeline/TimelinePost.tsx rename to src/_app/(menu)/_components/timeline/TimelinePost.tsx index 50043c7c..65d7289f 100644 --- a/src/app/(menu)/_components/timeline/TimelinePost.tsx +++ b/src/_app/(menu)/_components/timeline/TimelinePost.tsx @@ -1,8 +1,8 @@ 'use client'; import { usePost } from '@/swr/client/post'; -import ViewTrigger from '@/app/(menu)/_components/timeline/ViewportTrigger'; -import Post from '@/app/(menu)/_components/timeline/layouts/Post'; +import ViewTrigger from '@/_app/(menu)/_components/timeline/ViewportTrigger'; +import Post from '@/_app/(menu)/_components/timeline/layouts/Post'; import { UserPost } from '@cuculus/cuculus-api'; /** diff --git a/src/app/(menu)/_components/timeline/ViewportTrigger.tsx b/src/_app/(menu)/_components/timeline/ViewportTrigger.tsx similarity index 100% rename from src/app/(menu)/_components/timeline/ViewportTrigger.tsx rename to src/_app/(menu)/_components/timeline/ViewportTrigger.tsx diff --git a/src/app/(menu)/_components/timeline/elements/AvatarIcon.tsx b/src/_app/(menu)/_components/timeline/elements/AvatarIcon.tsx similarity index 100% rename from src/app/(menu)/_components/timeline/elements/AvatarIcon.tsx rename to src/_app/(menu)/_components/timeline/elements/AvatarIcon.tsx diff --git a/src/app/(menu)/_components/timeline/elements/FavoriteButton.tsx b/src/_app/(menu)/_components/timeline/elements/FavoriteButton.tsx similarity index 100% rename from src/app/(menu)/_components/timeline/elements/FavoriteButton.tsx rename to src/_app/(menu)/_components/timeline/elements/FavoriteButton.tsx diff --git a/src/app/(menu)/_components/timeline/elements/MomentAgo.tsx b/src/_app/(menu)/_components/timeline/elements/MomentAgo.tsx similarity index 100% rename from src/app/(menu)/_components/timeline/elements/MomentAgo.tsx rename to src/_app/(menu)/_components/timeline/elements/MomentAgo.tsx diff --git a/src/app/(menu)/_components/timeline/elements/ReplyButton.tsx b/src/_app/(menu)/_components/timeline/elements/ReplyButton.tsx similarity index 100% rename from src/app/(menu)/_components/timeline/elements/ReplyButton.tsx rename to src/_app/(menu)/_components/timeline/elements/ReplyButton.tsx diff --git a/src/app/(menu)/_components/timeline/elements/RepostButton.tsx b/src/_app/(menu)/_components/timeline/elements/RepostButton.tsx similarity index 100% rename from src/app/(menu)/_components/timeline/elements/RepostButton.tsx rename to src/_app/(menu)/_components/timeline/elements/RepostButton.tsx diff --git a/src/app/(menu)/_components/timeline/elements/ShareButton.tsx b/src/_app/(menu)/_components/timeline/elements/ShareButton.tsx similarity index 100% rename from src/app/(menu)/_components/timeline/elements/ShareButton.tsx rename to src/_app/(menu)/_components/timeline/elements/ShareButton.tsx diff --git a/src/app/(menu)/_components/timeline/layouts/Post.stories.ts b/src/_app/(menu)/_components/timeline/layouts/Post.stories.ts similarity index 100% rename from src/app/(menu)/_components/timeline/layouts/Post.stories.ts rename to src/_app/(menu)/_components/timeline/layouts/Post.stories.ts diff --git a/src/app/(menu)/_components/timeline/layouts/Post.tsx b/src/_app/(menu)/_components/timeline/layouts/Post.tsx similarity index 90% rename from src/app/(menu)/_components/timeline/layouts/Post.tsx rename to src/_app/(menu)/_components/timeline/layouts/Post.tsx index 22e81948..a0879c95 100644 --- a/src/app/(menu)/_components/timeline/layouts/Post.tsx +++ b/src/_app/(menu)/_components/timeline/layouts/Post.tsx @@ -2,12 +2,12 @@ import { CardActionArea, styled, Tooltip, Typography } from '@mui/material'; import Link from 'next/link'; -import FavoriteButton from '@/app/(menu)/_components/timeline/elements/FavoriteButton'; -import RepostButton from '@/app/(menu)/_components/timeline/elements/RepostButton'; +import FavoriteButton from '@/_app/(menu)/_components/timeline/elements/FavoriteButton'; +import RepostButton from '@/_app/(menu)/_components/timeline/elements/RepostButton'; import { useRouter } from 'next/navigation'; -import MomentAgo from '@/app/(menu)/_components/timeline/elements/MomentAgo'; +import MomentAgo from '@/_app/(menu)/_components/timeline/elements/MomentAgo'; import { format } from 'date-fns'; -import AvatarIcon from '@/app/(menu)/_components/timeline/elements/AvatarIcon'; +import AvatarIcon from '@/_app/(menu)/_components/timeline/elements/AvatarIcon'; const Article = styled('article')` border-bottom: 1px solid ${({ theme }) => theme.palette.grey[100]}; @@ -108,6 +108,8 @@ export default function Post({ void router.prefetch(postUrl)} + onMouseEnter={() => void router.prefetch(postUrl)} onClick={() => { const selection = window.getSelection(); if (!(selection && selection.toString())) { @@ -123,7 +125,6 @@ export default function Post({
event.stopPropagation()} > @@ -134,7 +135,6 @@ export default function Post({ event.stopPropagation()} diff --git a/src/app/(menu)/_components/timeline/layouts/Showmore.tsx b/src/_app/(menu)/_components/timeline/layouts/Showmore.tsx similarity index 100% rename from src/app/(menu)/_components/timeline/layouts/Showmore.tsx rename to src/_app/(menu)/_components/timeline/layouts/Showmore.tsx diff --git a/src/app/(menu)/layout.tsx b/src/_app/(menu)/layout.tsx similarity index 80% rename from src/app/(menu)/layout.tsx rename to src/_app/(menu)/layout.tsx index 9b1cab43..c38c44ec 100644 --- a/src/app/(menu)/layout.tsx +++ b/src/_app/(menu)/layout.tsx @@ -1,10 +1,10 @@ 'use client'; import { styled } from '@mui/material'; -import SideMenu from '@/app/(menu)/_components/menu/SideMenu'; -import BottomMenu from '@/app/(menu)/_components/menu/BottomMenu'; +import SideMenu from '@/_app/(menu)/_components/menu/SideMenu'; +import BottomMenu from '@/_app/(menu)/_components/menu/BottomMenu'; import { ReactNode } from 'react'; -import MobileOpenPostDialogButton from '@/app/(menu)/_components/menu/elements/MobileOpenPostDialogButton'; +import MobileOpenPostDialogButton from '@/_app/(menu)/_components/menu/elements/MobileOpenPostDialogButton'; const Layout = styled('div')` display: grid; diff --git a/src/_app/(plain)/(guest)/layout.tsx b/src/_app/(plain)/(guest)/layout.tsx new file mode 100644 index 00000000..eb3139a1 --- /dev/null +++ b/src/_app/(plain)/(guest)/layout.tsx @@ -0,0 +1,8 @@ +'use client'; + +import { ReactNode } from 'react'; +import GuestRoute from '@/_app/_components/auth/GuestRoute'; + +export default function Layout({ children }: { children: ReactNode }) { + return {children}; +} diff --git a/src/app/(plain)/(guest)/login/_components/LoginForm.tsx b/src/_app/(plain)/(guest)/login/_components/LoginForm.tsx similarity index 100% rename from src/app/(plain)/(guest)/login/_components/LoginForm.tsx rename to src/_app/(plain)/(guest)/login/_components/LoginForm.tsx diff --git a/src/app/(plain)/(guest)/signup/_components/SignUpForm.tsx b/src/_app/(plain)/(guest)/signup/_components/SignUpForm.tsx similarity index 84% rename from src/app/(plain)/(guest)/signup/_components/SignUpForm.tsx rename to src/_app/(plain)/(guest)/signup/_components/SignUpForm.tsx index 821b33e9..1b2fadfd 100644 --- a/src/app/(plain)/(guest)/signup/_components/SignUpForm.tsx +++ b/src/_app/(plain)/(guest)/signup/_components/SignUpForm.tsx @@ -2,10 +2,10 @@ import { useState } from 'react'; import { useSystem } from '@/swr/client/system'; -import StepInvitationCode from '@/app/(plain)/(guest)/signup/_components/layouts/StepInvitationCode'; -import StepEmail from '@/app/(plain)/(guest)/signup/_components/layouts/StepEmail'; -import StepVerifyCode from '@/app/(plain)/(guest)/signup/_components/layouts/StepVerifyCode'; -import StepSignup from '@/app/(plain)/(guest)/signup/_components/layouts/StepSignup'; +import StepInvitationCode from '@/_app/(plain)/(guest)/signup/_components/layouts/StepInvitationCode'; +import StepEmail from '@/_app/(plain)/(guest)/signup/_components/layouts/StepEmail'; +import StepVerifyCode from '@/_app/(plain)/(guest)/signup/_components/layouts/StepVerifyCode'; +import StepSignup from '@/_app/(plain)/(guest)/signup/_components/layouts/StepSignup'; import { useRouter } from 'next/navigation'; export default function SignUpForm() { diff --git a/src/app/(plain)/(guest)/signup/_components/layouts/StepEmail.tsx b/src/_app/(plain)/(guest)/signup/_components/layouts/StepEmail.tsx similarity index 93% rename from src/app/(plain)/(guest)/signup/_components/layouts/StepEmail.tsx rename to src/_app/(plain)/(guest)/signup/_components/layouts/StepEmail.tsx index 1a3910f6..5987a031 100644 --- a/src/app/(plain)/(guest)/signup/_components/layouts/StepEmail.tsx +++ b/src/_app/(plain)/(guest)/signup/_components/layouts/StepEmail.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { OutlinedInput } from '@mui/material'; -import StepTemplate from '@/app/(plain)/(guest)/signup/_components/layouts/StepTemplate'; +import StepTemplate from '@/_app/(plain)/(guest)/signup/_components/layouts/StepTemplate'; import { usePreSignUp } from '@/swr/client/auth'; type Props = { diff --git a/src/app/(plain)/(guest)/signup/_components/layouts/StepInvitationCode.tsx b/src/_app/(plain)/(guest)/signup/_components/layouts/StepInvitationCode.tsx similarity index 92% rename from src/app/(plain)/(guest)/signup/_components/layouts/StepInvitationCode.tsx rename to src/_app/(plain)/(guest)/signup/_components/layouts/StepInvitationCode.tsx index ce83a878..d155cfbd 100644 --- a/src/app/(plain)/(guest)/signup/_components/layouts/StepInvitationCode.tsx +++ b/src/_app/(plain)/(guest)/signup/_components/layouts/StepInvitationCode.tsx @@ -1,7 +1,7 @@ import { useInvitationVerify } from '@/swr/client/invitations'; import { useState } from 'react'; import { OutlinedInput } from '@mui/material'; -import StepTemplate from '@/app/(plain)/(guest)/signup/_components/layouts/StepTemplate'; +import StepTemplate from '@/_app/(plain)/(guest)/signup/_components/layouts/StepTemplate'; type Props = { step: number; diff --git a/src/app/(plain)/(guest)/signup/_components/layouts/StepSignup.tsx b/src/_app/(plain)/(guest)/signup/_components/layouts/StepSignup.tsx similarity index 96% rename from src/app/(plain)/(guest)/signup/_components/layouts/StepSignup.tsx rename to src/_app/(plain)/(guest)/signup/_components/layouts/StepSignup.tsx index dbaec0c1..ac9ad86a 100644 --- a/src/app/(plain)/(guest)/signup/_components/layouts/StepSignup.tsx +++ b/src/_app/(plain)/(guest)/signup/_components/layouts/StepSignup.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { IconButton, InputAdornment, OutlinedInput } from '@mui/material'; -import StepTemplate from '@/app/(plain)/(guest)/signup/_components/layouts/StepTemplate'; +import StepTemplate from '@/_app/(plain)/(guest)/signup/_components/layouts/StepTemplate'; import { useSignUp } from '@/swr/client/auth'; import { Visibility, VisibilityOff } from '@mui/icons-material'; diff --git a/src/app/(plain)/(guest)/signup/_components/layouts/StepTemplate.tsx b/src/_app/(plain)/(guest)/signup/_components/layouts/StepTemplate.tsx similarity index 100% rename from src/app/(plain)/(guest)/signup/_components/layouts/StepTemplate.tsx rename to src/_app/(plain)/(guest)/signup/_components/layouts/StepTemplate.tsx diff --git a/src/app/(plain)/(guest)/signup/_components/layouts/StepVerifyCode.tsx b/src/_app/(plain)/(guest)/signup/_components/layouts/StepVerifyCode.tsx similarity index 92% rename from src/app/(plain)/(guest)/signup/_components/layouts/StepVerifyCode.tsx rename to src/_app/(plain)/(guest)/signup/_components/layouts/StepVerifyCode.tsx index 207f7b3a..6d9c399a 100644 --- a/src/app/(plain)/(guest)/signup/_components/layouts/StepVerifyCode.tsx +++ b/src/_app/(plain)/(guest)/signup/_components/layouts/StepVerifyCode.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { OutlinedInput } from '@mui/material'; -import StepTemplate from '@/app/(plain)/(guest)/signup/_components/layouts/StepTemplate'; +import StepTemplate from '@/_app/(plain)/(guest)/signup/_components/layouts/StepTemplate'; import { useVerifyCode } from '@/swr/client/auth'; type Props = { diff --git a/src/_app/(plain)/(private)/layout.tsx b/src/_app/(plain)/(private)/layout.tsx new file mode 100644 index 00000000..ad5be002 --- /dev/null +++ b/src/_app/(plain)/(private)/layout.tsx @@ -0,0 +1,8 @@ +'use client'; + +import { ReactNode, useEffect } from 'react'; +import PrivateRoute from '@/_app/_components/auth/PrivateRoute'; + +export default function Layout({ children }: { children: ReactNode }) { + return {children}; +} diff --git a/src/app/(plain)/(private)/logout/_components/Logout.tsx b/src/_app/(plain)/(private)/logout/_components/Logout.tsx similarity index 94% rename from src/app/(plain)/(private)/logout/_components/Logout.tsx rename to src/_app/(plain)/(private)/logout/_components/Logout.tsx index b28cae4f..ff3c3094 100644 --- a/src/app/(plain)/(private)/logout/_components/Logout.tsx +++ b/src/_app/(plain)/(private)/logout/_components/Logout.tsx @@ -1,7 +1,7 @@ 'use client'; import { Button, Dialog, styled } from '@mui/material'; -import CapsuleButton from '@/app/_components/button/CapsuleButton'; +import CapsuleButton from '@/_app/_components/button/CapsuleButton'; import { useRouter } from 'next/navigation'; import { useSignOut } from '@/swr/client/auth'; diff --git a/src/_app/(plain)/README.md b/src/_app/(plain)/README.md new file mode 100644 index 00000000..dc19a21a --- /dev/null +++ b/src/_app/(plain)/README.md @@ -0,0 +1,11 @@ +# [@/_app/(plain)](.) +特に決まったレイアウトを持たない画面グループです。 + +## [@/_app/(plain)/(guest)](./(guest)) +非ログインであることが必須のページ + +## [@/_app/(plain)/(private)](./(private)) +ログインが必須のページ + +## [@/_app/(plain)/_components](./_components) +`@/_app/(plain)`配下で使用するコンポーネント置き場です。 diff --git a/src/app/(plain)/_components/Footer.tsx b/src/_app/(plain)/_components/Footer.tsx similarity index 92% rename from src/app/(plain)/_components/Footer.tsx rename to src/_app/(plain)/_components/Footer.tsx index 9e1367b3..6ad5421d 100644 --- a/src/app/(plain)/_components/Footer.tsx +++ b/src/_app/(plain)/_components/Footer.tsx @@ -1,7 +1,7 @@ 'use client'; -import GitHubLink from '@/app/_components/button/GitHubLink'; -import LinkButton from '@/app/_components/button/LinkButton'; +import GitHubLink from '@/_app/_components/button/GitHubLink'; +import LinkButton from '@/_app/_components/button/LinkButton'; import { styled } from '@mui/material'; const StyledFooter = styled('footer')` diff --git a/src/app/(plain)/_components/LoadingScreen.tsx b/src/_app/(plain)/_components/LoadingScreen.tsx similarity index 100% rename from src/app/(plain)/_components/LoadingScreen.tsx rename to src/_app/(plain)/_components/LoadingScreen.tsx diff --git a/src/app/README.md b/src/_app/README.md similarity index 69% rename from src/app/README.md rename to src/_app/README.md index 7b6ce645..12df6e0f 100644 --- a/src/app/README.md +++ b/src/_app/README.md @@ -1,11 +1,11 @@ -## [@/app/(menu)](./(menu)) +## [@/_app/(menu)](./(menu)) メニューを持つ画面グループです。 -## [@/app/(plain)](./(plain)) +## [@/_app/(plain)](./(plain)) 特に決まったレイアウトを持たない画面グループです。 -## [@/app/_components](./_components) +## [@/_app/_components](./_components) 複数の場所で使用できる汎用的なコンポーネント置き場です。 -## [@/app/_providers](./_providers) +## [@/_app/_providers](./_providers) コンテキストを配下コンポーネントに提供するコンポーネント置き場です。 diff --git a/src/app/_components/NotFound.tsx b/src/_app/_components/NotFound.tsx similarity index 95% rename from src/app/_components/NotFound.tsx rename to src/_app/_components/NotFound.tsx index 08d4f12e..7360e2f4 100644 --- a/src/app/_components/NotFound.tsx +++ b/src/_app/_components/NotFound.tsx @@ -1,7 +1,7 @@ 'use client'; import { styled } from '@mui/material'; -import LinkButton from '@/app/_components/button/LinkButton'; +import LinkButton from '@/_app/_components/button/LinkButton'; import { MuseoModerno } from 'next/font/google'; const museoModerno = MuseoModerno({ subsets: ['latin'], weight: ['700'] }); diff --git a/src/_app/_components/auth/GuestRoute.tsx b/src/_app/_components/auth/GuestRoute.tsx new file mode 100644 index 00000000..25adebe1 --- /dev/null +++ b/src/_app/_components/auth/GuestRoute.tsx @@ -0,0 +1,30 @@ +'use client'; + +import { ReactNode, useEffect } from 'react'; +import { useAuth } from '@/swr/client/auth'; +import { useRouter } from 'next/navigation'; +import LoadingScreen from '@/_app/(plain)/_components/LoadingScreen'; + +export default function GuestRoute({ + children, + showLoadingScreen = true, +}: { + children: ReactNode; + showLoadingScreen?: boolean; +}) { + const { data, isLoading } = useAuth(); + const router = useRouter(); + + useEffect(() => { + if (data) { + // redirect('/home'); + router.replace('/home'); + } + }, [data]); + + if (showLoadingScreen && isLoading) { + return ; + } + + return <>{children}; +} diff --git a/src/_app/_components/auth/PrivateRoute.tsx b/src/_app/_components/auth/PrivateRoute.tsx new file mode 100644 index 00000000..a3202f5a --- /dev/null +++ b/src/_app/_components/auth/PrivateRoute.tsx @@ -0,0 +1,30 @@ +'use client'; + +import { ReactNode, useEffect } from 'react'; +import { useAuth } from '@/swr/client/auth'; +import { useRouter } from 'next/navigation'; +import LoadingScreen from '@/_app/(plain)/_components/LoadingScreen'; + +export default function PrivateRoute({ + children, + showLoadingScreen = true, +}: { + children: ReactNode; + showLoadingScreen?: boolean; +}) { + const { data, isLoading } = useAuth(); + const router = useRouter(); + + useEffect(() => { + if (!isLoading && !data) { + // redirect('/'); + router.replace('/'); + } + }, [data, isLoading]); + + if (showLoadingScreen && isLoading) { + return ; + } + + return <>{data && children}; +} diff --git a/src/app/_components/button/BackButton.stories.ts b/src/_app/_components/button/BackButton.stories.ts similarity index 100% rename from src/app/_components/button/BackButton.stories.ts rename to src/_app/_components/button/BackButton.stories.ts diff --git a/src/app/_components/button/BackButton.tsx b/src/_app/_components/button/BackButton.tsx similarity index 100% rename from src/app/_components/button/BackButton.tsx rename to src/_app/_components/button/BackButton.tsx diff --git a/src/app/_components/button/Button.tsx b/src/_app/_components/button/Button.tsx similarity index 100% rename from src/app/_components/button/Button.tsx rename to src/_app/_components/button/Button.tsx diff --git a/src/app/_components/button/CapsuleButton.stories.ts b/src/_app/_components/button/CapsuleButton.stories.ts similarity index 100% rename from src/app/_components/button/CapsuleButton.stories.ts rename to src/_app/_components/button/CapsuleButton.stories.ts diff --git a/src/app/_components/button/CapsuleButton.tsx b/src/_app/_components/button/CapsuleButton.tsx similarity index 100% rename from src/app/_components/button/CapsuleButton.tsx rename to src/_app/_components/button/CapsuleButton.tsx diff --git a/src/app/_components/button/CapsuleLoadingButton.tsx b/src/_app/_components/button/CapsuleLoadingButton.tsx similarity index 100% rename from src/app/_components/button/CapsuleLoadingButton.tsx rename to src/_app/_components/button/CapsuleLoadingButton.tsx diff --git a/src/app/_components/button/GitHubLink.tsx b/src/_app/_components/button/GitHubLink.tsx similarity index 100% rename from src/app/_components/button/GitHubLink.tsx rename to src/_app/_components/button/GitHubLink.tsx diff --git a/src/app/_components/button/IconButton.stories.tsx b/src/_app/_components/button/IconButton.stories.tsx similarity index 100% rename from src/app/_components/button/IconButton.stories.tsx rename to src/_app/_components/button/IconButton.stories.tsx diff --git a/src/app/_components/button/IconButton.tsx b/src/_app/_components/button/IconButton.tsx similarity index 100% rename from src/app/_components/button/IconButton.tsx rename to src/_app/_components/button/IconButton.tsx diff --git a/src/app/_components/button/LinkButton.tsx b/src/_app/_components/button/LinkButton.tsx similarity index 100% rename from src/app/_components/button/LinkButton.tsx rename to src/_app/_components/button/LinkButton.tsx diff --git a/src/app/_components/button/LoadingButton.tsx b/src/_app/_components/button/LoadingButton.tsx similarity index 100% rename from src/app/_components/button/LoadingButton.tsx rename to src/_app/_components/button/LoadingButton.tsx diff --git a/src/app/_components/post/ConfirmClosePostDialogDialog.tsx b/src/_app/_components/post/ConfirmClosePostDialogDialog.tsx similarity index 100% rename from src/app/_components/post/ConfirmClosePostDialogDialog.tsx rename to src/_app/_components/post/ConfirmClosePostDialogDialog.tsx diff --git a/src/app/_components/post/PostDialog.tsx b/src/_app/_components/post/PostDialog.tsx similarity index 93% rename from src/app/_components/post/PostDialog.tsx rename to src/_app/_components/post/PostDialog.tsx index a7e79ebd..9ded94f8 100644 --- a/src/app/_components/post/PostDialog.tsx +++ b/src/_app/_components/post/PostDialog.tsx @@ -1,8 +1,8 @@ 'use client'; -import ConfirmClosePostDialogDialog from '@/app/_components/post/ConfirmClosePostDialogDialog'; -import PostForm from '@/app/_components/post/PostForm'; -import SendPostButton from '@/app/_components/post/elements/SendPostButton'; +import ConfirmClosePostDialogDialog from '@/_app/_components/post/ConfirmClosePostDialogDialog'; +import PostForm from '@/_app/_components/post/PostForm'; +import SendPostButton from '@/_app/_components/post/elements/SendPostButton'; import { Close } from '@mui/icons-material'; import { Alert, diff --git a/src/app/_components/post/PostForm.tsx b/src/_app/_components/post/PostForm.tsx similarity index 95% rename from src/app/_components/post/PostForm.tsx rename to src/_app/_components/post/PostForm.tsx index 6f9effe0..bfa89298 100644 --- a/src/app/_components/post/PostForm.tsx +++ b/src/_app/_components/post/PostForm.tsx @@ -1,6 +1,6 @@ 'use client'; -import Editor from '@/app/_components/post/elements/Editor'; +import Editor from '@/_app/_components/post/elements/Editor'; import { useProfile } from '@/swr/client/auth'; import { Avatar, Box, styled } from '@mui/material'; diff --git a/src/app/_components/post/elements/Editor.tsx b/src/_app/_components/post/elements/Editor.tsx similarity index 100% rename from src/app/_components/post/elements/Editor.tsx rename to src/_app/_components/post/elements/Editor.tsx diff --git a/src/app/_components/post/elements/SendPostButton.tsx b/src/_app/_components/post/elements/SendPostButton.tsx similarity index 93% rename from src/app/_components/post/elements/SendPostButton.tsx rename to src/_app/_components/post/elements/SendPostButton.tsx index 2d79087e..1307d1dd 100644 --- a/src/app/_components/post/elements/SendPostButton.tsx +++ b/src/_app/_components/post/elements/SendPostButton.tsx @@ -1,6 +1,6 @@ 'use client'; -import CapsuleButton from '@/app/_components/button/CapsuleButton'; +import CapsuleButton from '@/_app/_components/button/CapsuleButton'; import { Send } from '@mui/icons-material'; import { usePostSend } from '@/swr/client/post'; diff --git a/src/app/layout.tsx b/src/_app/layout.tsx similarity index 98% rename from src/app/layout.tsx rename to src/_app/layout.tsx index 008615b9..017be1e5 100644 --- a/src/app/layout.tsx +++ b/src/_app/layout.tsx @@ -1,5 +1,3 @@ -import '@/styles/globals.css'; - import type { Metadata } from 'next'; import { Viewport } from 'next'; import CssBaseline from '@mui/material/CssBaseline'; diff --git a/src/app/(menu)/(private)/home/page.tsx b/src/app/(menu)/(private)/home/page.tsx deleted file mode 100644 index e49677b4..00000000 --- a/src/app/(menu)/(private)/home/page.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn'; -import { Metadata } from 'next'; -import HomeTimeline from '@/app/(menu)/(private)/home/_components/HomeTimeline'; - -export const metadata: Metadata = { - title: 'ホーム', -}; - -export default function page() { - return ( - - - - ); -} diff --git a/src/app/(menu)/(private)/invitations/page.tsx b/src/app/(menu)/(private)/invitations/page.tsx deleted file mode 100644 index a8c460d1..00000000 --- a/src/app/(menu)/(private)/invitations/page.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import Invitations from '@/app/(menu)/(private)/invitations/_components/Invitations'; -import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn'; - -export default function page() { - return ( - - - - ); -} diff --git a/src/app/(menu)/(private)/layout.tsx b/src/app/(menu)/(private)/layout.tsx deleted file mode 100644 index 43703d29..00000000 --- a/src/app/(menu)/(private)/layout.tsx +++ /dev/null @@ -1,17 +0,0 @@ -'use client'; - -import { useAuth } from '@/swr/client/auth'; -import { ReactNode, useEffect } from 'react'; -import { redirect } from 'next/navigation'; - -export default function Layout({ children }: { children: ReactNode }) { - const { data, isLoading } = useAuth(); - - useEffect(() => { - if (!isLoading && !data) { - redirect('/'); - } - }, [data, isLoading]); - - return <>{data && children}; -} diff --git a/src/app/(menu)/(private)/messages/page.tsx b/src/app/(menu)/(private)/messages/page.tsx deleted file mode 100644 index dda72fb0..00000000 --- a/src/app/(menu)/(private)/messages/page.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import ComingSoon from '@/app/(menu)/_components/main/ComingSoon'; -import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn'; - -export default function page() { - return ( - - - - ); -} diff --git a/src/app/(menu)/(private)/notifications/page.tsx b/src/app/(menu)/(private)/notifications/page.tsx deleted file mode 100644 index f6c4567b..00000000 --- a/src/app/(menu)/(private)/notifications/page.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import ComingSoon from '@/app/(menu)/_components/main/ComingSoon'; -import { Metadata } from 'next'; -import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn'; - -export const metadata: Metadata = { - title: '通知', -}; - -export default function page() { - return ( - - - - ); -} diff --git a/src/app/(menu)/(private)/search/page.tsx b/src/app/(menu)/(private)/search/page.tsx deleted file mode 100644 index 5ce242f0..00000000 --- a/src/app/(menu)/(private)/search/page.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import ComingSoon from '@/app/(menu)/_components/main/ComingSoon'; -import { Metadata } from 'next'; -import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn'; - -export const metadata: Metadata = { - title: '検索', -}; - -export default function page() { - return ( - - - - ); -} diff --git a/src/app/(menu)/(private)/settings/page.tsx b/src/app/(menu)/(private)/settings/page.tsx deleted file mode 100644 index 0da09601..00000000 --- a/src/app/(menu)/(private)/settings/page.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import ComingSoon from '@/app/(menu)/_components/main/ComingSoon'; -import { Metadata } from 'next'; -import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn'; - -export const metadata: Metadata = { - title: '設定', -}; - -export default function page() { - return ( - - - - ); -} diff --git a/src/app/(menu)/(public)/[username]/followers/page.tsx b/src/app/(menu)/(public)/[username]/followers/page.tsx deleted file mode 100644 index acda81f8..00000000 --- a/src/app/(menu)/(public)/[username]/followers/page.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import ComingSoon from '@/app/(menu)/_components/main/ComingSoon'; -import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn'; - -export default function page({}: { params: { userName: string } }) { - return ( - - - - ); -} diff --git a/src/app/(menu)/(public)/[username]/following/page.tsx b/src/app/(menu)/(public)/[username]/following/page.tsx deleted file mode 100644 index acda81f8..00000000 --- a/src/app/(menu)/(public)/[username]/following/page.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import ComingSoon from '@/app/(menu)/_components/main/ComingSoon'; -import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn'; - -export default function page({}: { params: { userName: string } }) { - return ( - - - - ); -} diff --git a/src/app/(menu)/(public)/[username]/page.tsx b/src/app/(menu)/(public)/[username]/page.tsx deleted file mode 100644 index 6f14cfb2..00000000 --- a/src/app/(menu)/(public)/[username]/page.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { Metadata } from 'next'; -import { usersApi } from '@/libs/cuculus-client'; -import { notFound } from 'next/navigation'; -import ProfilePage from '@/app/(menu)/(public)/[username]/_components/ProfilePage'; - -type Params = { params: { username: string } }; - -async function fetchUser(username: string) { - try { - return await usersApi.getUserByUsername( - { username }, - { - next: { - revalidate: 300, - }, - }, - ); - } catch { - return undefined; - } -} - -export async function generateMetadata({ params }: Params): Promise { - const user = await fetchUser(params.username); - if (!user) { - return {}; - } - - const title = `${user.name} (@${user.username}) さん`; - const description = - user.bio.length > 0 - ? user.bio - : `${user.name} さんはCuculusを利用しています。`; - - return { - title, - description, - openGraph: { - title, - description, - siteName: 'Cuculus', - locale: 'ja_JP', - type: 'article', - images: [user.profileImageUrl], - }, - twitter: { - card: 'summary', - }, - }; -} - -export default async function page({ params }: Params) { - const user = await fetchUser(params.username); - if (!user) { - notFound(); - } - - return ; -} diff --git a/src/app/(menu)/(public)/[username]/posts/[postId]/page.tsx b/src/app/(menu)/(public)/[username]/posts/[postId]/page.tsx deleted file mode 100644 index bdd63725..00000000 --- a/src/app/(menu)/(public)/[username]/posts/[postId]/page.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { Metadata } from 'next'; -import { postsApi } from '@/libs/cuculus-client'; -import { notFound, redirect } from 'next/navigation'; -import { PostPage } from '@/app/(menu)/(public)/[username]/posts/_components/PostPage'; - -const TITLE_MAX_LENGTH = 70; - -type Params = { params: { username: string; postId: string } }; - -async function fetchPost(postId: string) { - try { - return await postsApi.getPost( - { id: postId }, - { - next: { - revalidate: 300, - }, - }, - ); - } catch { - return undefined; - } -} - -export async function generateMetadata({ params }: Params): Promise { - const post = await fetchPost(params.postId); - if (!post) { - return {}; - } - - let originalUser = post.author.name; - let originalPost = post.text ?? ''; - let originalImage = post.author.profileImageUrl; - - if (post.originalPost) { - originalUser = post.originalPost.author.name; - originalPost = post.originalPost.text ?? ''; - originalImage = post.originalPost.author.profileImageUrl; - } - - let title = `${originalUser}さん:「${originalPost}」`; - - // 最大長を超える場合は省略 - if (title.length > TITLE_MAX_LENGTH) { - title = title.substring(0, TITLE_MAX_LENGTH - 3) + '...'; - } - - return { - title, - openGraph: { - title: `${originalUser} さんの投稿`, - description: `「${originalPost}」`, - siteName: 'Cuculus', - locale: 'ja_JP', - type: 'article', - images: [originalImage], - }, - twitter: { - card: 'summary', - }, - }; -} - -export default async function page({ params }: Params) { - const post = await fetchPost(params.postId); - - // TODO 権限エラーの場合はそのままPostPageにundefinedを投げる - if (!post) { - notFound(); - } - - if (post.author.username !== params.username) { - redirect(`/${post.author.username}/posts/${post.id}`); - } - - return ; -} diff --git a/src/app/(menu)/README.md b/src/app/(menu)/README.md deleted file mode 100644 index 1e8ba326..00000000 --- a/src/app/(menu)/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# [@/app/(menu)](.) -メニューを持つ画面グループです。 - -## [@/app/(menu)/(private)](./(private)) -ログインが必須のページ - -## [@/app/(menu)/(public)](./(public)) -ログインしていても、してなくても良いページ - -## [@/app/(menu)/_components](./_components) -`@/app/(menu)`配下で使用するコンポーネント置き場です。 diff --git a/src/app/(plain)/(guest)/layout.tsx b/src/app/(plain)/(guest)/layout.tsx deleted file mode 100644 index a0794aac..00000000 --- a/src/app/(plain)/(guest)/layout.tsx +++ /dev/null @@ -1,22 +0,0 @@ -'use client'; - -import { useAuth } from '@/swr/client/auth'; -import { ReactNode, useEffect } from 'react'; -import { redirect } from 'next/navigation'; -import LoadingScreen from '@/app/(plain)/_components/LoadingScreen'; - -export default function Layout({ children }: { children: ReactNode }) { - const { data, isLoading } = useAuth(); - - useEffect(() => { - if (data) { - redirect('/home'); - } - }, [data]); - - if (isLoading) { - return ; - } - - return <>{children}; -} diff --git a/src/app/(plain)/(private)/layout.tsx b/src/app/(plain)/(private)/layout.tsx deleted file mode 100644 index 5007af05..00000000 --- a/src/app/(plain)/(private)/layout.tsx +++ /dev/null @@ -1,22 +0,0 @@ -'use client'; - -import { useAuth } from '@/swr/client/auth'; -import { ReactNode, useEffect } from 'react'; -import { redirect } from 'next/navigation'; -import LoadingScreen from '@/app/(plain)/_components/LoadingScreen'; - -export default function Layout({ children }: { children: ReactNode }) { - const { data, isLoading } = useAuth(); - - useEffect(() => { - if (!isLoading && !data) { - redirect('/'); - } - }, [data, isLoading]); - - if (isLoading) { - return ; - } - - return <>{data && children}; -} diff --git a/src/app/(plain)/(private)/logout/page.tsx b/src/app/(plain)/(private)/logout/page.tsx deleted file mode 100644 index 26ddd11c..00000000 --- a/src/app/(plain)/(private)/logout/page.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import Logout from '@/app/(plain)/(private)/logout/_components/Logout'; - -export default function page() { - return ( -
- -
- ); -} diff --git a/src/app/(plain)/README.md b/src/app/(plain)/README.md deleted file mode 100644 index b92e0bae..00000000 --- a/src/app/(plain)/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# [@/app/(plain)](.) -特に決まったレイアウトを持たない画面グループです。 - -## [@/app/(plain)/(guest)](./(guest)) -非ログインであることが必須のページ - -## [@/app/(plain)/(private)](./(private)) -ログインが必須のページ - -## [@/app/(plain)/_components](./_components) -`@/app/(plain)`配下で使用するコンポーネント置き場です。 diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx deleted file mode 100644 index 6d6732bd..00000000 --- a/src/app/not-found.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import NotFound from '@/app/_components/NotFound'; -import { Metadata } from 'next'; - -export const metadata: Metadata = { - title: 'ページが見つかりません', -}; - -export default function page() { - return ( -
- -
- ); -} diff --git a/src/app/robots.ts b/src/app/robots.ts deleted file mode 100644 index 444eeed2..00000000 --- a/src/app/robots.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { MetadataRoute } from 'next'; - -export default function robots(): MetadataRoute.Robots { - // Development robots.txt - if (process.env.STAGE !== 'production') { - return { - rules: { - userAgent: '*', - disallow: ['/'], - }, - }; - } - // Production robots.txt - return { - rules: [ - { - userAgent: 'Yahoo Pipes 1.0', - disallow: ['/'], - }, - { - userAgent: 'Livelapbot', - disallow: ['/'], - }, - { - userAgent: 'Megalodon', - disallow: ['/'], - }, - { - userAgent: 'ia_archiver', - disallow: ['/'], - }, - ], - sitemap: process.env.SITE_URL + '/sitemaps.xml', - }; -} diff --git a/src/pages/404.tsx b/src/pages/404.tsx new file mode 100644 index 00000000..fe8b63f9 --- /dev/null +++ b/src/pages/404.tsx @@ -0,0 +1,15 @@ +import NotFound from '@/_app/_components/NotFound'; + +// export const metadata: Metadata = { +// title: 'ページが見つかりません', +// }; + +const Page = () => { + return ( +
+ +
+ ); +}; + +export default Page; diff --git a/src/pages/[username]/followers/index.tsx b/src/pages/[username]/followers/index.tsx new file mode 100644 index 00000000..b4176c44 --- /dev/null +++ b/src/pages/[username]/followers/index.tsx @@ -0,0 +1,16 @@ +import ComingSoon from '@/_app/(menu)/_components/main/ComingSoon'; +import PrimaryColumn from '@/_app/(menu)/_components/main/PrimaryColumn'; +import MenuLayout from '@/_app/(menu)/layout'; +import { NextPageWithLayout } from 'next'; + +const Page: NextPageWithLayout = () => { + return ( + + + + ); +}; + +Page.getLayout = (children) => {children}; + +export default Page; diff --git a/src/pages/[username]/following/index.tsx b/src/pages/[username]/following/index.tsx new file mode 100644 index 00000000..59141751 --- /dev/null +++ b/src/pages/[username]/following/index.tsx @@ -0,0 +1,16 @@ +import ComingSoon from '@/_app/(menu)/_components/main/ComingSoon'; +import PrimaryColumn from '@/_app/(menu)/_components/main/PrimaryColumn'; +import { NextPageWithLayout } from 'next'; +import MenuLayout from '@/_app/(menu)/layout'; + +const Page: NextPageWithLayout = () => { + return ( + + + + ); +}; + +Page.getLayout = (children) => {children}; + +export default Page; diff --git a/src/pages/[username]/index.tsx b/src/pages/[username]/index.tsx new file mode 100644 index 00000000..0d2ea662 --- /dev/null +++ b/src/pages/[username]/index.tsx @@ -0,0 +1,59 @@ +import { + GetServerSideProps, + InferGetServerSidePropsType, + NextPageWithLayout, + PageProps, +} from 'next'; +import { usersApi } from '@/libs/cuculus-client'; +import ProfilePage from '@/_app/(menu)/(public)/[username]/_components/ProfilePage'; +import { UserWithFollows } from '@cuculus/cuculus-api'; +import MenuLayout from '@/_app/(menu)/layout'; + +async function fetchUser(username: string) { + try { + return await usersApi.getUserByUsername( + { username }, + { + next: { + revalidate: 300, + }, + }, + ); + } catch { + return undefined; + } +} + +export const getServerSideProps = (async (context) => { + const username = String(context.query.username); + const user = await fetchUser(username); + if (!user) { + return { + notFound: true, + }; + } + + const title = `${user.name} (@${user.username}) さん`; + const description = + user.bio.length > 0 + ? user.bio + : `${user.name} さんはCuculusを利用しています。`; + + return { + props: { + userJson: JSON.stringify(user), + metadata: { title, description, images: [user.profileImageUrl] }, + }, + }; +}) satisfies GetServerSideProps<{ userJson: string } & PageProps>; + +const Page: NextPageWithLayout< + InferGetServerSidePropsType +> = ({ userJson }) => { + const user = JSON.parse(userJson) as UserWithFollows; + return ; +}; + +Page.getLayout = (children) => {children}; + +export default Page; diff --git a/src/pages/[username]/posts/[postId]/index.tsx b/src/pages/[username]/posts/[postId]/index.tsx new file mode 100644 index 00000000..27822563 --- /dev/null +++ b/src/pages/[username]/posts/[postId]/index.tsx @@ -0,0 +1,86 @@ +import { + GetServerSideProps, + InferGetServerSidePropsType, + NextPageWithLayout, + PageProps, +} from 'next'; +import { postsApi } from '@/libs/cuculus-client'; +import { PostPage } from '@/_app/(menu)/(public)/[username]/posts/_components/PostPage'; +import { UserPost } from '@cuculus/cuculus-api'; +import MenuLayout from '@/_app/(menu)/layout'; + +const TITLE_MAX_LENGTH = 70; + +async function fetchPost(postId: string) { + try { + return await postsApi.getPost( + { id: postId }, + { + next: { + revalidate: 300, + }, + }, + ); + } catch { + return undefined; + } +} + +export const getServerSideProps = (async (context) => { + const postId = String(context.query.postId); + const post = await fetchPost(postId); + + // TODO 権限エラーの場合はそのままPostPageにundefinedを投げる + if (!post) { + return { + notFound: true, + }; + } + + const username = String(context.query.username); + + if (post.author.username !== username) { + return { + redirect: { + permanent: false, + destination: `/${post.author.username}/posts/${post.id}`, + }, + }; + } + + let originalUser = post.author.name; + let originalPost = post.text ?? ''; + let originalImage = post.author.profileImageUrl; + + if (post.originalPost) { + originalUser = post.originalPost.author.name; + originalPost = post.originalPost.text ?? ''; + originalImage = post.originalPost.author.profileImageUrl; + } + + let title = `${originalUser}さん:「${originalPost}」`; + + // 最大長を超える場合は省略 + if (title.length > TITLE_MAX_LENGTH) { + title = title.substring(0, TITLE_MAX_LENGTH - 3) + '...'; + } + + return { + props: { + postJson: JSON.stringify(post), + metadata: { title, description: `「${originalPost}」` }, + images: [originalImage], + }, + }; +}) satisfies GetServerSideProps<{ postJson: string } & PageProps>; + +const Page: NextPageWithLayout< + InferGetServerSidePropsType +> = ({ postJson }) => { + const post = JSON.parse(postJson) as UserPost; + return ; +}; + +Page.getLayout = (children) => {children}; + +export default Page; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx new file mode 100644 index 00000000..5cdc6b2a --- /dev/null +++ b/src/pages/_app.tsx @@ -0,0 +1,56 @@ +import { AppCacheProvider } from '@mui/material-nextjs/v13-pagesRouter'; +import CssBaseline from '@mui/material/CssBaseline'; +import theme from '@/theme/theme'; +import { ThemeProvider } from '@mui/material'; +import { AppPropsWithLayout } from 'next/app'; +import { ReactElement } from 'react'; +import PrivateRoute from '@/_app/_components/auth/PrivateRoute'; +import GuestRoute from '@/_app/_components/auth/GuestRoute'; +import MetaHead from './_meta'; + +function getAccessLevelRoute( + children: ReactElement, + accessLevel: 'private' | 'public' | 'guest', + showLoadingScreen: boolean, +) { + switch (accessLevel) { + case 'private': + return ( + + {children} + + ); + case 'guest': + return ( + + {children} + + ); + default: + return <>{children}; + } +} + +export default function App(props: AppPropsWithLayout) { + const { Component, pageProps } = props; + const getLayout = Component.getLayout || ((page) => page); + const accessLevel = Component.accessLevel ?? 'public'; + const showLoadingScreen = Component.getLayout === undefined; + return ( + <> + + + + + {getLayout( + getAccessLevelRoute( + , + accessLevel, + showLoadingScreen, + ), + )} + + + + ); +} diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx new file mode 100644 index 00000000..fdefd876 --- /dev/null +++ b/src/pages/_document.tsx @@ -0,0 +1,31 @@ +import { + DocumentContext, + DocumentProps, + Head, + Html, + Main, + NextScript, +} from 'next/document'; +import { + documentGetInitialProps, + DocumentHeadTags, + DocumentHeadTagsProps, +} from '@mui/material-nextjs/v13-pagesRouter'; + +export default function Document(props: DocumentProps & DocumentHeadTagsProps) { + return ( + + + + + +
+ + + + ); +} + +Document.getInitialProps = async (ctx: DocumentContext) => { + return await documentGetInitialProps(ctx); +}; diff --git a/src/pages/_meta.tsx b/src/pages/_meta.tsx new file mode 100644 index 00000000..aec37b6a --- /dev/null +++ b/src/pages/_meta.tsx @@ -0,0 +1,49 @@ +import { PageProps } from 'next'; +import Head from 'next/head'; + +const siteName = 'Cuculus'; + +export default function MetaHead({ metadata }: PageProps) { + const baseUrl = process.env.SITE_URL; + const title = metadata?.title ? `${metadata.title} | ${siteName}` : siteName; + const description = + metadata?.description ?? + 'Cuculusは新しいけどどこか懐かしい短文投稿サービスです。'; + const images = metadata?.images ?? [`${baseUrl}/icon.png`]; + + return ( + + + {title} + + + + + + + + + + + {images.map((url, i) => ( + + ))} + + + + + {images.map((url, i) => ( + + ))} + + + + ); +} diff --git a/src/app/(menu)/(public)/hashtag/.gitkeep b/src/pages/hashtag/.gitkeep similarity index 100% rename from src/app/(menu)/(public)/hashtag/.gitkeep rename to src/pages/hashtag/.gitkeep diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx new file mode 100644 index 00000000..914a0f49 --- /dev/null +++ b/src/pages/home/index.tsx @@ -0,0 +1,27 @@ +import PrimaryColumn from '@/_app/(menu)/_components/main/PrimaryColumn'; +import HomeTimeline from '@/_app/(menu)/(private)/home/_components/HomeTimeline'; +import { GetStaticProps, NextPageWithLayout, PageProps } from 'next'; +import MenuLayout from '@/_app/(menu)/layout'; + +export const getStaticProps = (() => { + return { + props: { + metadata: { + title: 'ホーム', + }, + }, + }; +}) satisfies GetStaticProps; +const Page: NextPageWithLayout = () => { + return ( + + + + ); +}; + +Page.getLayout = (children) => {children}; + +Page.accessLevel = 'private'; + +export default Page; diff --git a/src/app/(plain)/(guest)/page.tsx b/src/pages/index.tsx similarity index 85% rename from src/app/(plain)/(guest)/page.tsx rename to src/pages/index.tsx index 0903d57e..968888c0 100644 --- a/src/app/(plain)/(guest)/page.tsx +++ b/src/pages/index.tsx @@ -1,9 +1,8 @@ -'use client'; - import CuculusSvg from '@assets/icons/Cuculus.svg'; import { styled } from '@mui/material'; -import LinkButton from '@/app/_components/button/LinkButton'; -import Footer from '@/app/(plain)/_components/Footer'; +import LinkButton from '@/_app/_components/button/LinkButton'; +import Footer from '@/_app/(plain)/_components/Footer'; +import { NextPageWithLayout } from 'next'; const Container = styled('div')` display: flex; @@ -50,7 +49,7 @@ const StyledLinkButton = styled(LinkButton)` font-weight: bold; `; -export default function toppage() { +const Page: NextPageWithLayout = () => { return (
@@ -72,4 +71,8 @@ export default function toppage() {
); -} +}; + +Page.accessLevel = 'guest'; + +export default Page; diff --git a/src/pages/invitations/index.tsx b/src/pages/invitations/index.tsx new file mode 100644 index 00000000..e2009128 --- /dev/null +++ b/src/pages/invitations/index.tsx @@ -0,0 +1,28 @@ +import Invitations from '@/_app/(menu)/(private)/invitations/_components/Invitations'; +import PrimaryColumn from '@/_app/(menu)/_components/main/PrimaryColumn'; +import { GetStaticProps, NextPageWithLayout, PageProps } from 'next'; +import MenuLayout from '@/_app/(menu)/layout'; + +export const getStaticProps = (() => { + return { + props: { + metadata: { + title: '招待コード', + }, + }, + }; +}) satisfies GetStaticProps; + +const Page: NextPageWithLayout = () => { + return ( + + + + ); +}; + +Page.getLayout = (children) => {children}; + +Page.accessLevel = 'private'; + +export default Page; diff --git a/src/app/(plain)/(guest)/login/page.tsx b/src/pages/login/index.tsx similarity index 89% rename from src/app/(plain)/(guest)/login/page.tsx rename to src/pages/login/index.tsx index acad472f..10700b3e 100644 --- a/src/app/(plain)/(guest)/login/page.tsx +++ b/src/pages/login/index.tsx @@ -1,7 +1,6 @@ -'use client'; - import { styled } from '@mui/material'; -import LoginForm from '@/app/(plain)/(guest)/login/_components/LoginForm'; +import LoginForm from '@/_app/(plain)/(guest)/login/_components/LoginForm'; +import { NextPageWithLayout } from 'next'; const StyledLogin = styled('div')` display: grid; @@ -66,7 +65,7 @@ const Title = styled('div')` } `; -export default function page() { +const Page: NextPageWithLayout = () => { return (
@@ -83,4 +82,8 @@ export default function page() {
); -} +}; + +Page.accessLevel = 'guest'; + +export default Page; diff --git a/src/pages/logout/index.tsx b/src/pages/logout/index.tsx new file mode 100644 index 00000000..a4f98ad4 --- /dev/null +++ b/src/pages/logout/index.tsx @@ -0,0 +1,14 @@ +import Logout from '@/_app/(plain)/(private)/logout/_components/Logout'; +import { NextPageWithLayout } from 'next'; + +const Page: NextPageWithLayout = () => { + return ( +
+ +
+ ); +}; + +Page.accessLevel = 'private'; + +export default Page; diff --git a/src/pages/messages/index.tsx b/src/pages/messages/index.tsx new file mode 100644 index 00000000..a94846bd --- /dev/null +++ b/src/pages/messages/index.tsx @@ -0,0 +1,18 @@ +import ComingSoon from '@/_app/(menu)/_components/main/ComingSoon'; +import PrimaryColumn from '@/_app/(menu)/_components/main/PrimaryColumn'; +import MenuLayout from '@/_app/(menu)/layout'; +import { NextPageWithLayout } from 'next'; + +const Page: NextPageWithLayout = () => { + return ( + + + + ); +}; + +Page.getLayout = (children) => {children}; + +Page.accessLevel = 'private'; + +export default Page; diff --git a/src/pages/notifications/index.tsx b/src/pages/notifications/index.tsx new file mode 100644 index 00000000..1ad93bde --- /dev/null +++ b/src/pages/notifications/index.tsx @@ -0,0 +1,28 @@ +import ComingSoon from '@/_app/(menu)/_components/main/ComingSoon'; +import { GetStaticProps, NextPageWithLayout, PageProps } from 'next'; +import PrimaryColumn from '@/_app/(menu)/_components/main/PrimaryColumn'; +import MenuLayout from '@/_app/(menu)/layout'; + +export const getStaticProps = (() => { + return { + props: { + metadata: { + title: '通知', + }, + }, + }; +}) satisfies GetStaticProps; + +const Page: NextPageWithLayout = () => { + return ( + + + + ); +}; + +Page.getLayout = (children) => {children}; + +Page.accessLevel = 'private'; + +export default Page; diff --git a/src/pages/robots.txt.ts b/src/pages/robots.txt.ts new file mode 100644 index 00000000..34a14fcd --- /dev/null +++ b/src/pages/robots.txt.ts @@ -0,0 +1,73 @@ +import { GetServerSidePropsContext } from 'next'; + +type RobotsFile = { + rules: { userAgent: string; disallow?: string }[]; + sitemap?: string; +}; + +function generateRobots(): RobotsFile { + // Development robots.txt + if (process.env.STAGE !== 'production') { + return { + rules: [{ userAgent: '*', disallow: '/' }], + }; + } + // Production robots.txt + return { + rules: [ + { + userAgent: 'Yahoo Pipes 1.0', + disallow: '/', + }, + { + userAgent: 'Livelapbot', + disallow: '/', + }, + { + userAgent: 'Megalodon', + disallow: '/', + }, + { + userAgent: 'ia_archiver', + disallow: '/', + }, + ], + sitemap: process.env.SITE_URL + '/sitemaps.xml', + }; +} + +function generateRobotsTxt(robotsFile: RobotsFile): string { + const lines: string[] = []; + + robotsFile.rules.forEach((rule) => { + lines.push(`User-agent: ${rule.userAgent}`); + if (rule.disallow) { + lines.push(`Disallow: ${rule.disallow}`); + } + lines.push(''); + }); + + if (robotsFile.sitemap) { + lines.push(`Sitemap: ${robotsFile.sitemap}`); + } + + return lines.join('\n'); +} + +export function getServerSideProps({ res }: GetServerSidePropsContext) { + const robotsFile = generateRobots(); + const robots = generateRobotsTxt(robotsFile); + + res.setHeader('Cache-Control', 's-maxage=86400, stale-while-revalidate'); + res.setHeader('Content-Type', 'text/plain'); + res.write(robots); + res.end(); + + return { + props: {}, + }; +} + +export default function Robots() { + // getServerSideProps will do the heavy lifting +} diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx new file mode 100644 index 00000000..85e394bc --- /dev/null +++ b/src/pages/search/index.tsx @@ -0,0 +1,28 @@ +import ComingSoon from '@/_app/(menu)/_components/main/ComingSoon'; +import PrimaryColumn from '@/_app/(menu)/_components/main/PrimaryColumn'; +import MenuLayout from '@/_app/(menu)/layout'; +import { GetStaticProps, NextPageWithLayout, PageProps } from 'next'; + +export const getStaticProps = (() => { + return { + props: { + metadata: { + title: '検索', + }, + }, + }; +}) satisfies GetStaticProps; + +const Page: NextPageWithLayout = () => { + return ( + + + + ); +}; + +Page.getLayout = (children) => {children}; + +Page.accessLevel = 'private'; + +export default Page; diff --git a/src/pages/settings/index.tsx b/src/pages/settings/index.tsx new file mode 100644 index 00000000..a9873ac1 --- /dev/null +++ b/src/pages/settings/index.tsx @@ -0,0 +1,28 @@ +import ComingSoon from '@/_app/(menu)/_components/main/ComingSoon'; +import { GetStaticProps, NextPageWithLayout, PageProps } from 'next'; +import PrimaryColumn from '@/_app/(menu)/_components/main/PrimaryColumn'; +import MenuLayout from '@/_app/(menu)/layout'; + +export const getStaticProps = (() => { + return { + props: { + metadata: { + title: '設定', + }, + }, + }; +}) satisfies GetStaticProps; + +const Page: NextPageWithLayout = () => { + return ( + + + + ); +}; + +Page.getLayout = (children) => {children}; + +Page.accessLevel = 'private'; + +export default Page; diff --git a/src/app/(plain)/(guest)/signup/page.tsx b/src/pages/signup/index.tsx similarity index 87% rename from src/app/(plain)/(guest)/signup/page.tsx rename to src/pages/signup/index.tsx index a36932a0..b8edc878 100644 --- a/src/app/(plain)/(guest)/signup/page.tsx +++ b/src/pages/signup/index.tsx @@ -1,7 +1,6 @@ -'use client'; - import { styled } from '@mui/material'; -import SignUpForm from '@/app/(plain)/(guest)/signup/_components/SignUpForm'; +import SignUpForm from '@/_app/(plain)/(guest)/signup/_components/SignUpForm'; +import { NextPageWithLayout } from 'next'; const Root = styled('div')` display: grid; @@ -61,7 +60,7 @@ const Title = styled('div')` } `; -export default function page() { +const Page: NextPageWithLayout = () => { return (
@@ -75,4 +74,8 @@ export default function page() {
); -} +}; + +Page.accessLevel = 'guest'; + +export default Page; diff --git a/src/styles/globals.css b/src/styles/globals.css deleted file mode 100644 index ec2585e8..00000000 --- a/src/styles/globals.css +++ /dev/null @@ -1,13 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} diff --git a/src/types/next.d.ts b/src/types/next.d.ts new file mode 100644 index 00000000..38519d7e --- /dev/null +++ b/src/types/next.d.ts @@ -0,0 +1,25 @@ +import { NextPage, NextPageWithLayout, PageProps } from 'next'; +import { ReactElement, ReactNode } from 'react'; +import { AppProps } from 'next/app'; + +declare module 'next' { + type PageProps = { + metadata?: { + title?: string; + description?: string; + images?: Array; + }; + }; + + type NextPageWithLayout

= NextPage & { + getLayout?: (page: ReactElement) => ReactNode; + accessLevel?: 'private' | 'public' | 'guest'; + }; +} + +declare module 'next/app' { + type AppPropsWithLayout = Omit & { + Component: NextPageWithLayout; + pageProps: PageProps; + }; +}