From b0fb9e14d6b0b024b5365e38f456c0388865acdb Mon Sep 17 00:00:00 2001 From: NaveOWO <87578512+NaveOWO@users.noreply.github.com> Date: Wed, 22 May 2024 16:30:07 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20msw=EC=A0=81=EC=9A=A9=20&=20context?= =?UTF-8?q?=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/desktop/package.json | 8 + apps/desktop/public/mockServiceWorker.js | 284 +++++++++++++ .../src/@components/@common/Modal/index.tsx | 237 ----------- .../@components/@common/audioFileUpload.tsx | 87 ---- .../@common/{ => button}/backButton.tsx | 12 +- .../@common/button/customButton.tsx | 23 - .../@common/button/standardButton.tsx | 34 -- .../src/@components/@common/checkBox.tsx | 23 +- .../src/@components/@common/filter.tsx | 158 +++---- .../@common/{ => form}/inputContainer.tsx | 6 +- .../@common/{ => hashtag}/hashTag.tsx | 0 .../src/@components/@common/homeLogo.tsx | 13 +- .../@common/{ => layout}/footer.tsx | 32 +- .../@common/{ => layout}/header.tsx | 0 .../{Layout/index.tsx => layout/layout.tsx} | 0 .../@common/{ => layout}/styledComponents.ts | 0 .../@common/{ => modal}/conventionModal.tsx | 14 +- .../src/@components/@common/player.tsx | 197 ++++----- .../src/@components/@common/selectBox.tsx | 71 ++-- .../src/@components/@common/switch.tsx | 78 ++-- .../src/@components/about/aboutMain.tsx | 97 ----- .../desktop/src/@components/about/aboutUs.tsx | 178 -------- .../src/@components/about/howToUse.tsx | 229 ---------- apps/desktop/src/@components/about/index.tsx | 38 -- .../src/@components/admin/adminHeader.tsx | 107 ----- .../@components/admin/event/eventUpload.tsx | 173 -------- apps/desktop/src/@components/admin/index.tsx | 11 - apps/desktop/src/@components/error/index.tsx | 19 +- .../src/@components/event/eventDetail.tsx | 115 ----- .../src/@components/event/eventList.tsx | 96 ----- .../src/@components/event/hotEvent.tsx | 92 ---- apps/desktop/src/@components/event/index.tsx | 50 --- .../forgotPassword/forgotPasswordInput.tsx | 49 +-- .../src/@components/forgotPassword/index.tsx | 14 +- .../passwordContainer.tsx | 6 +- .../src/@components/login/loginForm.tsx | 250 +++++------ .../src/@components/login/switchToggle.tsx | 22 +- .../src/@components/main/eventInfo.tsx | 83 ---- .../src/@components/main/eventSection.tsx | 89 ---- apps/desktop/src/@components/main/index.tsx | 56 +-- .../desktop/src/@components/main/loginBtn.tsx | 137 +++--- .../src/@components/main/mainBanner.tsx | 331 ++++++++------- .../src/@components/main/mainHeader.tsx | 11 +- apps/desktop/src/@components/main/mainNav.tsx | 114 +++-- .../src/@components/main/profileBox.tsx | 142 +++---- .../@components/main/recentInfoSection.tsx | 75 ---- .../src/@components/main/recentTrackItem.tsx | 188 --------- .../src/@components/main/recentTrackList.tsx | 36 -- .../src/@components/main/recentVocalItem.tsx | 203 --------- .../src/@components/main/recentVocalList.tsx | 39 -- .../@components/mobileLanding/engLinkBox.tsx | 67 --- .../mobileLanding/englishVersion.tsx | 242 ----------- .../src/@components/mobileLanding/index.tsx | 37 -- .../@components/mobileLanding/korLinkBox.tsx | 68 --- .../mobileLanding/koreaVersion.tsx | 280 ------------- .../mobileLanding/mobileHeader.tsx | 65 --- .../portfolio/musicInformation.tsx | 12 +- .../portfolio/portfolioUpdateModal.tsx | 60 ++- .../portfolio/producerPortfolio.tsx | 40 +- .../@components/portfolio/vocalPortfolio.tsx | 40 +- .../ProducerVocalSearchingPortfolio.tsx | 40 +- .../src/@components/producerProfile/index.tsx | 75 ++-- .../producerPortfolioInform.tsx | 30 +- .../producerProfile/producerPortfolioList.tsx | 27 +- .../producerProfile/producerProfileShadow.tsx | 30 +- .../producerVocalSearching.tsx | 37 +- .../producerVocalSearchingInform.tsx | 41 +- .../tracksProfileUploadModal.tsx | 16 +- .../producerProfile/viewMoreButton.tsx | 16 +- .../vocalSearchingMusicInform.tsx | 12 +- .../src/@components/profile/hashtag.tsx | 6 +- .../desktop/src/@components/profile/index.tsx | 28 +- .../profile/producerProfileImage.tsx | 8 +- .../profile/profileDescription.tsx | 6 +- .../@components/profile/profileHashtags.tsx | 8 +- .../@components/profile/vocalProfileImage.tsx | 6 +- .../profileEdit/descriptionInput.tsx | 72 ++++ .../producerContactEdit.tsx | 8 +- .../producerProfileEdit/producerImageEdit.tsx | 10 +- .../producerProfileEdit/producerNameEdit.tsx | 14 +- .../producerProfileEditContainer.tsx | 51 ++- .../profileContact.tsx | 8 +- .../profileEdit/profileDescriptionEdit.tsx | 8 +- .../profileEdit/profileHashtagEdit.tsx | 20 +- .../profileNickname.tsx | 18 +- .../profileEdit/profileSelectCategoryEdit.tsx | 16 +- .../vocalProfileEdit/vocalContactEdit.tsx | 8 +- .../vocalProfileEdit/vocalImageEdit.tsx | 12 +- .../vocalProfileEdit/vocalNameEdit.tsx | 14 +- .../vocalProfileEditContainer.tsx | 52 ++- .../vocalProfileEdit/vocalSleeper.tsx | 4 +- .../src/@components/resetPassword/index.tsx | 20 +- .../resetPassword/passwordContainer.tsx | 54 +++ .../resetPassword/resetPasswordInput.tsx | 31 +- .../src/@components/signUp/profileContact.tsx | 28 ++ .../src/@components/signUp/signupProfile.tsx | 40 +- .../src/@components/signUp/signupSeccess.tsx | 12 +- .../src/@components/signUp/signupStep.tsx | 36 +- .../@components/trackPost/audioCategory.tsx | 12 +- .../trackPost/audioDescription.tsx | 10 +- .../@components/trackPost/audioHashtags.tsx | 12 +- .../trackPost/audioJacketImage.tsx | 18 +- .../src/@components/trackPost/audioTitle.tsx | 8 +- .../src/@components/trackPost/commentBox.tsx | 79 ++-- .../trackPost/commentContentLength.tsx | 12 +- .../trackPost/commentFileInput.tsx | 17 +- .../src/@components/trackPost/commentInfo.tsx | 29 +- .../@components/trackPost/commentLayout.tsx | 5 +- .../trackPost/commentProfileEventBox.tsx | 20 +- .../trackPost/commentTextInput.tsx | 8 +- .../@components/trackPost/commentWrite.tsx | 12 +- .../trackPost/commentWriteLayout.tsx | 6 +- .../commentWriteProfileContainer.tsx | 2 +- .../src/@components/trackPost/comments.tsx | 69 +-- .../src/@components/trackPost/download.tsx | 65 +-- .../@components/trackPost/editDropDown.tsx | 19 +- .../trackPost/editDropDownComment.tsx | 17 +- .../src/@components/trackPost/index.tsx | 130 ++---- .../@components/trackPost/producerProfile.tsx | 15 +- .../src/@components/trackPost/showMore.tsx | 14 +- .../src/@components/trackSearch/listTitle.tsx | 39 +- .../src/@components/trackSearch/trackItem.tsx | 150 ++++--- .../src/@components/trackSearch/trackList.tsx | 36 +- .../trackSearchHeader/PageTypeNav.tsx | 22 +- .../trackSearchHeader/trackSearchHeader.tsx | 8 +- .../trackSearchHeaderButton.tsx | 4 +- .../trackSearch/uploadButtonModal.tsx | 12 +- .../src/@components/upload/categotyInfo.tsx | 29 +- .../@components/upload/descriptionInfo.tsx | 10 +- .../{@common => upload}/descriptionInput.tsx | 17 +- .../src/@components/upload/fileUploadInfo.tsx | 7 +- .../src/@components/upload/imageInfo.tsx | 13 +- .../upload/producer/producerLayout.tsx | 14 +- .../@components/upload/producerUploadBody.tsx | 38 +- .../src/@components/upload/uploadHeader.tsx | 2 +- .../src/@components/upload/uploadInfoBox.tsx | 5 +- .../src/@components/upload/uploadTitle.tsx | 14 +- .../@components/upload/vocal/vocalLayout.tsx | 15 +- .../@components/upload/vocalUploadBody.tsx | 21 +- .../src/@components/vocalProfile/index.tsx | 35 +- .../vocalProfile/vocalPortfolioInform.tsx | 38 +- .../vocalProfile/vocalPortfolioList.tsx | 28 +- .../src/@components/vocalSearch/vocalItem.tsx | 200 ++++----- .../src/@components/vocalSearch/vocalList.tsx | 67 ++- apps/desktop/src/@pages/aboutPage.tsx | 10 - apps/desktop/src/@pages/adminPage.tsx | 21 - apps/desktop/src/@pages/eventPage.tsx | 10 - .../desktop/src/@pages/forgotPasswordPage.tsx | 2 +- apps/desktop/src/@pages/loginPage.tsx | 8 +- apps/desktop/src/@pages/mainPage.tsx | 2 +- apps/desktop/src/@pages/mobileLandingPage.tsx | 10 - .../src/@pages/producerProfilePage.tsx | 3 +- apps/desktop/src/@pages/profileEditPage.tsx | 4 +- apps/desktop/src/@pages/resetPasswordPage.tsx | 2 +- apps/desktop/src/@pages/signupProfilePage.tsx | 2 +- apps/desktop/src/@pages/signupStepPage.tsx | 4 +- apps/desktop/src/@pages/signupSuccessPage.tsx | 2 +- apps/desktop/src/@pages/trackPostPage.tsx | 15 +- apps/desktop/src/@pages/trackSearchPage.tsx | 84 ++-- apps/desktop/src/@pages/uploadEditPage.tsx | 6 +- apps/desktop/src/@pages/uploadPage.tsx | 4 +- apps/desktop/src/@pages/vocalProfilePage.tsx | 2 +- apps/desktop/src/@pages/vocalSearchPage.tsx | 32 +- apps/desktop/src/App.tsx | 8 +- apps/desktop/src/Router.tsx | 7 - apps/desktop/src/api/comments.ts | 33 +- apps/desktop/src/api/common/client.ts | 2 +- apps/desktop/src/api/mocks/browser.ts | 4 + apps/desktop/src/api/mocks/comments.ts | 26 ++ apps/desktop/src/api/mocks/handlers.ts | 394 ++++++++++++++++++ apps/desktop/src/api/mocks/login.ts | 18 + apps/desktop/src/api/mocks/producerProfile.ts | 65 +++ apps/desktop/src/api/mocks/sources.ts | 140 +++++++ apps/desktop/src/api/mocks/trackDetails.ts | 25 ++ apps/desktop/src/api/mocks/tracks.ts | 24 ++ apps/desktop/src/api/mocks/vocalProfile.ts | 37 ++ apps/desktop/src/api/mocks/vocals.ts | 25 ++ apps/desktop/src/api/mypage.ts | 30 +- apps/desktop/src/api/path.ts | 54 ++- apps/desktop/src/api/profile.ts | 52 +-- apps/desktop/src/api/tracks.ts | 24 +- .../upload/producer/editProducerPortfolio.ts | 1 - .../api/upload/producer/editVocalSearching.ts | 1 - .../api/upload/vocal/editVocalPortfolio.ts | 1 - .../api/upload/vocal/uploadVocalPortfolio.ts | 1 - apps/desktop/src/api/user.ts | 13 +- apps/desktop/src/api/vocals.ts | 18 +- apps/desktop/src/assets/audio/Brunch.mp3 | 1 + apps/desktop/src/assets/audio/bonfire.mp3 | Bin 0 -> 2666298 bytes .../audio/\353\264\204\353\264\204_.mp3" | 1 + apps/desktop/src/assets/image/profile1.jpeg | Bin 0 -> 153461 bytes apps/desktop/src/assets/image/profile10.jpeg | Bin 0 -> 30718 bytes apps/desktop/src/assets/image/profile12.jpeg | Bin 0 -> 19490 bytes apps/desktop/src/assets/image/profile2.jpeg | Bin 0 -> 46587 bytes apps/desktop/src/assets/image/profile3.jpeg | Bin 0 -> 29637 bytes apps/desktop/src/assets/image/profile4.jpeg | Bin 0 -> 44053 bytes apps/desktop/src/assets/image/profile5.jpeg | Bin 0 -> 93299 bytes apps/desktop/src/assets/image/profile6.jpeg | Bin 0 -> 42989 bytes apps/desktop/src/assets/image/profile7.jpeg | Bin 0 -> 48916 bytes apps/desktop/src/assets/image/profile8.jpeg | Bin 0 -> 22267 bytes apps/desktop/src/assets/image/profile9.jpeg | Bin 0 -> 187857 bytes apps/desktop/src/assets/image/zizi.jpeg | Bin 0 -> 83858 bytes apps/desktop/src/context/playerContext.tsx | 70 ++-- apps/desktop/src/core/common/inputState.ts | 9 +- apps/desktop/src/core/common/routes.ts | 46 +- apps/desktop/src/core/login/test | 0 apps/desktop/src/core/main/test | 0 .../src/core/producerPortfolioEdit/test | 0 apps/desktop/src/core/producerProfile/test | 0 .../desktop/src/core/producerProfileEdit/test | 0 apps/desktop/src/core/resetPassword/test | 0 apps/desktop/src/core/trackPost/test | 0 apps/desktop/src/core/trackSearch/test | 0 apps/desktop/src/core/upload/test | 0 apps/desktop/src/core/vocalPortfolioEdit/test | 0 apps/desktop/src/core/vocalProfile/test | 0 apps/desktop/src/core/vocalProfileEdit/test | 0 apps/desktop/src/core/vocalSearch/test | 0 .../src/hooks/common/useInfiniteScroll.ts | 18 +- apps/desktop/src/hooks/common/useModal.ts | 23 +- apps/desktop/src/hooks/common/usePlay.ts | 7 +- .../src/hooks/common/usePlaySelectedTrack.ts | 18 +- apps/desktop/src/hooks/common/useRouter.ts | 29 ++ .../src/hooks/common/useUploadAudioFile.ts | 19 +- .../forgotPassword/useForgotPasswordData.ts | 3 +- apps/desktop/src/hooks/login/test | 0 .../src/hooks/producerPortfolioEdit/test | 0 apps/desktop/src/hooks/producerProfile/test | 0 .../useSelectCategories.ts | 21 +- apps/desktop/src/hooks/queries/comments.ts | 40 +- apps/desktop/src/hooks/queries/mypage.ts | 133 ++---- apps/desktop/src/hooks/queries/tracks.ts | 37 +- apps/desktop/src/hooks/queries/vocals.ts | 40 +- apps/desktop/src/hooks/resetPassword/test | 0 apps/desktop/src/index.tsx | 18 +- .../src/recoil/common/loginUserData.ts | 3 +- apps/desktop/src/recoil/common/profile.ts | 14 +- .../src/recoil/trackPost/commentWriteData.ts | 16 +- apps/desktop/src/type/api.ts | 6 +- apps/desktop/src/type/comments.ts | 5 +- apps/desktop/src/type/common/routes.ts | 4 - apps/desktop/src/type/mypage.ts | 6 +- apps/desktop/src/type/profile.ts | 16 +- .../desktop/src/type/trackPost/commentType.ts | 4 +- apps/desktop/src/type/tracks.ts | 11 +- apps/desktop/src/type/vocals.ts | 3 +- .../src/utils/common/createContext.tsx | 66 +++ apps/desktop/src/validations/test | 0 apps/mobile/src/Router.tsx | 12 +- .../SignupProfile/ProfileDescriptionEdit.tsx | 5 +- apps/mobile/src/utils/common/check.ts | 2 +- yarn.lock | 294 ++++++++++++- 252 files changed, 3881 insertions(+), 5908 deletions(-) create mode 100644 apps/desktop/public/mockServiceWorker.js delete mode 100644 apps/desktop/src/@components/@common/Modal/index.tsx delete mode 100644 apps/desktop/src/@components/@common/audioFileUpload.tsx rename apps/desktop/src/@components/@common/{ => button}/backButton.tsx (64%) delete mode 100644 apps/desktop/src/@components/@common/button/customButton.tsx delete mode 100644 apps/desktop/src/@components/@common/button/standardButton.tsx rename apps/desktop/src/@components/@common/{ => form}/inputContainer.tsx (90%) rename apps/desktop/src/@components/@common/{ => hashtag}/hashTag.tsx (100%) rename apps/desktop/src/@components/@common/{ => layout}/footer.tsx (68%) rename apps/desktop/src/@components/@common/{ => layout}/header.tsx (100%) rename apps/desktop/src/@components/@common/{Layout/index.tsx => layout/layout.tsx} (100%) rename apps/desktop/src/@components/@common/{ => layout}/styledComponents.ts (100%) rename apps/desktop/src/@components/@common/{ => modal}/conventionModal.tsx (86%) delete mode 100644 apps/desktop/src/@components/about/aboutMain.tsx delete mode 100644 apps/desktop/src/@components/about/aboutUs.tsx delete mode 100644 apps/desktop/src/@components/about/howToUse.tsx delete mode 100644 apps/desktop/src/@components/about/index.tsx delete mode 100644 apps/desktop/src/@components/admin/adminHeader.tsx delete mode 100644 apps/desktop/src/@components/admin/event/eventUpload.tsx delete mode 100644 apps/desktop/src/@components/admin/index.tsx delete mode 100644 apps/desktop/src/@components/event/eventDetail.tsx delete mode 100644 apps/desktop/src/@components/event/eventList.tsx delete mode 100644 apps/desktop/src/@components/event/hotEvent.tsx delete mode 100644 apps/desktop/src/@components/event/index.tsx rename apps/desktop/src/@components/{@common => forgotPassword}/passwordContainer.tsx (92%) delete mode 100644 apps/desktop/src/@components/main/eventInfo.tsx delete mode 100644 apps/desktop/src/@components/main/eventSection.tsx delete mode 100644 apps/desktop/src/@components/main/recentInfoSection.tsx delete mode 100644 apps/desktop/src/@components/main/recentTrackItem.tsx delete mode 100644 apps/desktop/src/@components/main/recentTrackList.tsx delete mode 100644 apps/desktop/src/@components/main/recentVocalItem.tsx delete mode 100644 apps/desktop/src/@components/main/recentVocalList.tsx delete mode 100644 apps/desktop/src/@components/mobileLanding/engLinkBox.tsx delete mode 100644 apps/desktop/src/@components/mobileLanding/englishVersion.tsx delete mode 100644 apps/desktop/src/@components/mobileLanding/index.tsx delete mode 100644 apps/desktop/src/@components/mobileLanding/korLinkBox.tsx delete mode 100644 apps/desktop/src/@components/mobileLanding/koreaVersion.tsx delete mode 100644 apps/desktop/src/@components/mobileLanding/mobileHeader.tsx create mode 100644 apps/desktop/src/@components/profileEdit/descriptionInput.tsx rename apps/desktop/src/@components/{@common => profileEdit}/profileContact.tsx (70%) rename apps/desktop/src/@components/{@common => profileEdit}/profileNickname.tsx (73%) create mode 100644 apps/desktop/src/@components/resetPassword/passwordContainer.tsx create mode 100644 apps/desktop/src/@components/signUp/profileContact.tsx rename apps/desktop/src/@components/{@common => upload}/descriptionInput.tsx (77%) delete mode 100644 apps/desktop/src/@pages/aboutPage.tsx delete mode 100644 apps/desktop/src/@pages/adminPage.tsx delete mode 100644 apps/desktop/src/@pages/eventPage.tsx delete mode 100644 apps/desktop/src/@pages/mobileLandingPage.tsx create mode 100644 apps/desktop/src/api/mocks/browser.ts create mode 100644 apps/desktop/src/api/mocks/comments.ts create mode 100644 apps/desktop/src/api/mocks/handlers.ts create mode 100644 apps/desktop/src/api/mocks/login.ts create mode 100644 apps/desktop/src/api/mocks/producerProfile.ts create mode 100644 apps/desktop/src/api/mocks/sources.ts create mode 100644 apps/desktop/src/api/mocks/trackDetails.ts create mode 100644 apps/desktop/src/api/mocks/tracks.ts create mode 100644 apps/desktop/src/api/mocks/vocalProfile.ts create mode 100644 apps/desktop/src/api/mocks/vocals.ts delete mode 100644 apps/desktop/src/api/upload/producer/editProducerPortfolio.ts delete mode 100644 apps/desktop/src/api/upload/producer/editVocalSearching.ts delete mode 100644 apps/desktop/src/api/upload/vocal/editVocalPortfolio.ts delete mode 100644 apps/desktop/src/api/upload/vocal/uploadVocalPortfolio.ts create mode 100644 apps/desktop/src/assets/audio/Brunch.mp3 create mode 100644 apps/desktop/src/assets/audio/bonfire.mp3 create mode 100644 "apps/desktop/src/assets/audio/\353\264\204\353\264\204_.mp3" create mode 100644 apps/desktop/src/assets/image/profile1.jpeg create mode 100644 apps/desktop/src/assets/image/profile10.jpeg create mode 100644 apps/desktop/src/assets/image/profile12.jpeg create mode 100644 apps/desktop/src/assets/image/profile2.jpeg create mode 100644 apps/desktop/src/assets/image/profile3.jpeg create mode 100644 apps/desktop/src/assets/image/profile4.jpeg create mode 100644 apps/desktop/src/assets/image/profile5.jpeg create mode 100644 apps/desktop/src/assets/image/profile6.jpeg create mode 100644 apps/desktop/src/assets/image/profile7.jpeg create mode 100644 apps/desktop/src/assets/image/profile8.jpeg create mode 100644 apps/desktop/src/assets/image/profile9.jpeg create mode 100644 apps/desktop/src/assets/image/zizi.jpeg delete mode 100644 apps/desktop/src/core/login/test delete mode 100644 apps/desktop/src/core/main/test delete mode 100644 apps/desktop/src/core/producerPortfolioEdit/test delete mode 100644 apps/desktop/src/core/producerProfile/test delete mode 100644 apps/desktop/src/core/producerProfileEdit/test delete mode 100644 apps/desktop/src/core/resetPassword/test delete mode 100644 apps/desktop/src/core/trackPost/test delete mode 100644 apps/desktop/src/core/trackSearch/test delete mode 100644 apps/desktop/src/core/upload/test delete mode 100644 apps/desktop/src/core/vocalPortfolioEdit/test delete mode 100644 apps/desktop/src/core/vocalProfile/test delete mode 100644 apps/desktop/src/core/vocalProfileEdit/test delete mode 100644 apps/desktop/src/core/vocalSearch/test create mode 100644 apps/desktop/src/hooks/common/useRouter.ts delete mode 100644 apps/desktop/src/hooks/login/test delete mode 100644 apps/desktop/src/hooks/producerPortfolioEdit/test delete mode 100644 apps/desktop/src/hooks/producerProfile/test delete mode 100644 apps/desktop/src/hooks/resetPassword/test delete mode 100644 apps/desktop/src/type/common/routes.ts create mode 100644 apps/desktop/src/utils/common/createContext.tsx delete mode 100644 apps/desktop/src/validations/test diff --git a/apps/desktop/package.json b/apps/desktop/package.json index d279392b3..88084b903 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -11,6 +11,8 @@ "babel-eslint": "^10.1.0", "file-saver": "^2.0.5", "jszip": "^3.10.1", + "msw": "^2.2.14", + "qs": "^6.12.1", "react": "^18.2.0", "react-cookie": "^4.1.1", "react-device-detect": "^2.2.3", @@ -20,6 +22,7 @@ "react-router-dom": "^6.5.0", "react-scripts": "5.0.1", "react-textarea-autosize": "^8.4.1", + "react-uuid": "^2.0.0", "recoil": "^0.7.6", "recoil-persist": "^4.2.0", "styled-components": "^5.3.6", @@ -78,5 +81,10 @@ "jest": "^29.3.1", "prettier": "^2.8.1", "ts-jest": "^29.0.3" + }, + "msw": { + "workerDirectory": [ + "public" + ] } } diff --git a/apps/desktop/public/mockServiceWorker.js b/apps/desktop/public/mockServiceWorker.js new file mode 100644 index 000000000..e891a6854 --- /dev/null +++ b/apps/desktop/public/mockServiceWorker.js @@ -0,0 +1,284 @@ +/* eslint-disable */ +/* tslint:disable */ + +/** + * Mock Service Worker. + * @see https://github.com/mswjs/msw + * - Please do NOT modify this file. + * - Please do NOT serve this file on production. + */ + +const PACKAGE_VERSION = '2.2.14' +const INTEGRITY_CHECKSUM = '26357c79639bfa20d64c0efca2a87423' +const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') +const activeClientIds = new Set() + +self.addEventListener('install', function () { + self.skipWaiting() +}) + +self.addEventListener('activate', function (event) { + event.waitUntil(self.clients.claim()) +}) + +self.addEventListener('message', async function (event) { + const clientId = event.source.id + + if (!clientId || !self.clients) { + return + } + + const client = await self.clients.get(clientId) + + if (!client) { + return + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }) + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }) + break + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: { + packageVersion: PACKAGE_VERSION, + checksum: INTEGRITY_CHECKSUM, + }, + }) + break + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId) + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: true, + }) + break + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId) + break + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId) + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId + }) + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister() + } + + break + } + } +}) + +self.addEventListener('fetch', function (event) { + const { request } = event + + // Bypass navigation requests. + if (request.mode === 'navigate') { + return + } + + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { + return + } + + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return + } + + // Generate unique request ID. + const requestId = crypto.randomUUID() + event.respondWith(handleRequest(event, requestId)) +}) + +async function handleRequest(event, requestId) { + const client = await resolveMainClient(event) + const response = await getResponse(event, client, requestId) + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + ;(async function () { + const responseClone = response.clone() + + sendToClient( + client, + { + type: 'RESPONSE', + payload: { + requestId, + isMockedResponse: IS_MOCKED_RESPONSE in response, + type: responseClone.type, + status: responseClone.status, + statusText: responseClone.statusText, + body: responseClone.body, + headers: Object.fromEntries(responseClone.headers.entries()), + }, + }, + [responseClone.body], + ) + })() + } + + return response +} + +// Resolve the main client for the given event. +// Client that issues a request doesn't necessarily equal the client +// that registered the worker. It's with the latter the worker should +// communicate with during the response resolving phase. +async function resolveMainClient(event) { + const client = await self.clients.get(event.clientId) + + if (client?.frameType === 'top-level') { + return client + } + + const allClients = await self.clients.matchAll({ + type: 'window', + }) + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible' + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id) + }) +} + +async function getResponse(event, client, requestId) { + const { request } = event + + // Clone the request because it might've been already used + // (i.e. its body has been read and sent to the client). + const requestClone = request.clone() + + function passthrough() { + const headers = Object.fromEntries(requestClone.headers.entries()) + + // Remove internal MSW request header so the passthrough request + // complies with any potential CORS preflight checks on the server. + // Some servers forbid unknown request headers. + delete headers['x-msw-intention'] + + return fetch(requestClone, { headers }) + } + + // Bypass mocking when the client is not active. + if (!client) { + return passthrough() + } + + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return passthrough() + } + + // Notify the client that a request has been intercepted. + const requestBuffer = await request.arrayBuffer() + const clientMessage = await sendToClient( + client, + { + type: 'REQUEST', + payload: { + id: requestId, + url: request.url, + mode: request.mode, + method: request.method, + headers: Object.fromEntries(request.headers.entries()), + cache: request.cache, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body: requestBuffer, + keepalive: request.keepalive, + }, + }, + [requestBuffer], + ) + + switch (clientMessage.type) { + case 'MOCK_RESPONSE': { + return respondWithMock(clientMessage.data) + } + + case 'PASSTHROUGH': { + return passthrough() + } + } + + return passthrough() +} + +function sendToClient(client, message, transferrables = []) { + return new Promise((resolve, reject) => { + const channel = new MessageChannel() + + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error) + } + + resolve(event.data) + } + + client.postMessage( + message, + [channel.port2].concat(transferrables.filter(Boolean)), + ) + }) +} + +async function respondWithMock(response) { + // Setting response status code to 0 is a no-op. + // However, when responding with a "Response.error()", the produced Response + // instance will have status code set to 0. Since it's not possible to create + // a Response instance with status code 0, handle that use-case separately. + if (response.status === 0) { + return Response.error() + } + + const mockedResponse = new Response(response.body, response) + + Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, { + value: true, + enumerable: true, + }) + + return mockedResponse +} diff --git a/apps/desktop/src/@components/@common/Modal/index.tsx b/apps/desktop/src/@components/@common/Modal/index.tsx deleted file mode 100644 index b7ee56940..000000000 --- a/apps/desktop/src/@components/@common/Modal/index.tsx +++ /dev/null @@ -1,237 +0,0 @@ -import { ReactNode } from "react"; -import * as Dialog from '@radix-ui/react-dialog'; -import styled from "styled-components"; -import { SignUpModalXIc } from "../../../assets"; -import { useState } from 'react' -import { useGetEventList } from "../../../hooks/queries/admin/event"; -import { useNavigate } from "react-router-dom"; -import { setCookie } from "../../../utils/common/cookie"; - - -export function PopupModal() { - const [isOpen, setIsOpen] = useState(true) - const [checkedState, setCheckedState] = useState(false) - - const { eventListData } = useGetEventList({ - page: 1, - limit: 6, - }); - - - - const navigate = useNavigate(); - - function handleCheckedBox() { - setCheckedState(!checkedState) - } - - function handleCloseModal() { - setIsOpen(!isOpen) - } - - function handleClickCloseBtn() { - if (checkedState) { - const expiresDate = new Date(); - expiresDate.setDate(expiresDate.getDate() + 1); - setCookie('popup', checkedState, { path: "/", expires: expiresDate }) - } - } - - - return ( - <> - {eventListData && - - - { eventListData[0].eventTitle} - - - - - - - - { - `[Track-1 Song Camp Pt.1: Romance] - -#Korea Track -Track-1 Song Camp Korea는 다른 인디 아티스트와 협업하여 결과물을 도출하는 온라인 송캠프 프로그램으로,1위 팀은 믹싱/마스터링부터 유통까지 앨범 제작 전체 지원\n`} - {navigate(`/event/${eventListData[0].eventId}`)}}>모집 요강 상세 보기 - -{`\n\n#Global Track -Track-1 Song Camp Korea is an online song camp program where independent artists collaborate to produce outcomes. The 1st place team receives full support for the entire album production process, from mixing/mastering to distribution.\n` - } - {navigate(`/event/${eventListData[1].eventId}`)}}>View detailed recruitment guidelines. - - - - - - 오늘하루 보지 않기 - - - - - - - - - - - } - - ) -} - - - -const ModalWrapper = styled.div` - display: flex; - flex-direction: column; - justify-content: space-between; - - height: 100%; -` - -const ModalContent = styled.div` - width: 100%; -` - -const EventContent = styled.div` - ${({theme})=> theme.fonts.description}; - color: ${({ theme }) => theme.colors.gray2}; - - padding: 3rem 0; - - - overflow: hidden; - text-overflow: ellipsis; - white-space: pre-line; -` - -const EventDetailText = styled.span` - text-decoration: underline; - text-underline-offset: 0.3rem; - - cursor:pointer -` - -const PopupImageWrapper = styled.div` - display: flex; - justify-content: center; - width: 100%; -` -const PopupImage = styled.img` - width: 50%; -` - -const BottomWrapper = styled.div` - display: flex; - justify-content: space-between; - align-items: center; - - margin-top:2rem; -` - -const CheckBoxWrapper = styled.div` - display: flex; - align-items: center; - gap:1rem; - - width:100%; - height: 3rem; -` - -const CheckBoxLabel = styled.label` - ${({theme})=> theme.fonts.checkbox}; - color: ${({theme})=> theme.colors.gray2}; - - cursor: pointer; -` - -const CheckBox = styled.input` -appearance: none; - width: 2rem; - height: 2rem; - - border: 1px solid ${({theme})=> theme.colors.gray2}; - border-radius: 5px; - - &:checked { - border-color: transparent; - background-color: ${({theme})=>theme.colors.main}; - } -` - - - -export interface ModalProps { - children: ReactNode; - isOpen: boolean; - onClose: () => void; -} - -export default function Modal(props: ModalProps) { - const { children, isOpen, onClose } = props; - - return ( - - - - {children} - - - - ); -} - -const Styled = { - CloseIconWrapper: styled(Dialog.Close)` - width: 100%; - display: flex; - justify-content: flex-end; - `, - - ModalTitle: styled.h2` - display: flex; - justify-content: center; - width: 100%; - margin: 1rem 0 4rem; - - ${({theme})=> theme.fonts.pretendard_text20_700} - color: ${({ theme }) => theme.colors.white}; - - `, - Background: styled(Dialog.Overlay)` - background: rgba(0, 0, 0, 0.8); - position: fixed; - z-index: 1000; - inset: 0; - animation: overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1); - `, - - CloseIcon: styled(SignUpModalXIc)` - width: 3rem; - height: 3rem; - `, -}; - - - -const ModalContainer = styled(Dialog.Content)` - position: fixed; - top: 50%; - left: 50%; - - width: 68.6rem; - - padding: 3rem; - - border-radius: 1rem; - border: 1px solid #313338; - background: rgba(14, 15, 19, 0.8); - backdrop-filter: blur(10px); - box-shadow: hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px; - - transform: translate(-50%, -50%); -` diff --git a/apps/desktop/src/@components/@common/audioFileUpload.tsx b/apps/desktop/src/@components/@common/audioFileUpload.tsx deleted file mode 100644 index b0bb1bcee..000000000 --- a/apps/desktop/src/@components/@common/audioFileUpload.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import styled from "styled-components"; -import { FolderUploadIc } from "../../assets"; - -interface AudioFileUploadProps { - audioFileName: string; - audioFileType: string; - isTextOverflow: boolean; - handleUploadAudioFile: (e: React.ChangeEvent) => void; -} - -export default function AudioFileUpload(props: AudioFileUploadProps) { - const { audioFileName, audioFileType, isTextOverflow, handleUploadAudioFile } = props; - return ( - - - - {isTextOverflow && {audioFileType}} - - - - - - - ); -} - -const InputWrapper = styled.div` - display: flex; -`; - -const InputFileTextWrapper = styled.div<{ fileName: string }>` - height: 4.7rem; - width: 20.8rem; - - display: flex; - align-items: center; - border-bottom: 0.1rem solid - ${(props) => (props.fileName !== "" ? ({ theme }) => theme.colors.white : ({ theme }) => theme.colors.gray3)}; -`; - -const FileName = styled.input<{ isTextOverflow: boolean }>` - height: 2.5rem; - width: ${(props) => (props.isTextOverflow ? "16.4rem" : "100%")}; - - display: flex; - align-items: center; - - text-overflow: ${(props) => (props.isTextOverflow ? "ellipsis" : "default")}; - - ${({ theme }) => theme.fonts.hashtag}; - color: ${({ theme }) => theme.colors.white}; - margin-top: 1.686rem; - cursor: default; -`; - -const FileAttribute = styled.div<{ isTextOverflow: boolean }>` - height: 2.5rem; - width: ${(props) => (props.isTextOverflow ? "100%" : 0)}; - width: 100%; - - display: flex; - align-items: center; - ${({ theme }) => theme.fonts.hashtag}; - color: ${({ theme }) => theme.colors.white}; - margin-top: 1.686rem; -`; - -const FolderUploadIcon = styled(FolderUploadIc)` - width: 4rem; - height: 4rem; - margin-left: 1.2rem; - margin-top: 1.3rem; -`; - -const FileInput = styled.input` - display: none; -`; - -const FileLable = styled.label` - cursor: pointer; -`; diff --git a/apps/desktop/src/@components/@common/backButton.tsx b/apps/desktop/src/@components/@common/button/backButton.tsx similarity index 64% rename from apps/desktop/src/@components/@common/backButton.tsx rename to apps/desktop/src/@components/@common/button/backButton.tsx index 5546e0e0a..524f6968a 100644 --- a/apps/desktop/src/@components/@common/backButton.tsx +++ b/apps/desktop/src/@components/@common/button/backButton.tsx @@ -1,8 +1,7 @@ -import { useContext } from "react"; -import styled from "styled-components"; -import { BackButtonIc } from "../../assets"; -import { PlayerContext } from "../../context/playerContext"; -import usePrevPage from "../../hooks/common/usePrevPage"; +import styled from 'styled-components'; +import usePrevPage from '../../../hooks/common/usePrevPage'; +import { BackButtonIc } from '../../../assets'; +import { PlayUseContext } from '../../../context/playerContext'; interface BackButtonProps { staticPrevURL?: string | number; @@ -11,7 +10,7 @@ interface BackButtonProps { export default function BackButton(props: BackButtonProps) { const { staticPrevURL } = props; const { handleMovePrevPage } = usePrevPage(staticPrevURL); - const { quitAudioForMovePage } = useContext(PlayerContext); + const { quitAudioForMovePage } = PlayUseContext({}); return ( void; -} - -export default function CustomButton(props: PropsWithChildren) { - const { btnStyle, handleClickFunction, children } = props; - - return ( - - {children} - - ); -} - -const Container = styled.button` - display: flex; - justify-content: center; - align-items: center; -`; diff --git a/apps/desktop/src/@components/@common/button/standardButton.tsx b/apps/desktop/src/@components/@common/button/standardButton.tsx deleted file mode 100644 index a1e6f5de9..000000000 --- a/apps/desktop/src/@components/@common/button/standardButton.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { PropsWithChildren } from "react"; -import styled from "styled-components"; -import { theme } from "../../../style/theme"; - -interface StandardButtonProps { - bgColor: string; - fontColor: string; - handleClickFunction?: () => void; -} - -export default function StandardButton(props: PropsWithChildren) { - const { bgColor, fontColor, handleClickFunction, children } = props; - - return ( - - {children} - - ); -} - -const Container = styled.button<{ bgColor: string; fontColor: string }>` - display: flex; - justify-content: center; - align-items: center; - - width: 55.9rem; - height: 6.7rem; - - ${theme.fonts.body1}; - color: ${(props) => props.fontColor}; - background-color: ${(props) => props.bgColor}; - - border-radius: 3.35rem; -`; diff --git a/apps/desktop/src/@components/@common/checkBox.tsx b/apps/desktop/src/@components/@common/checkBox.tsx index 6e8934277..6e74ec41c 100644 --- a/apps/desktop/src/@components/@common/checkBox.tsx +++ b/apps/desktop/src/@components/@common/checkBox.tsx @@ -1,12 +1,8 @@ -import { createContext, PropsWithChildren, ReactElement, useState } from "react"; -import { useContextScope } from "../../hooks/common/useContextScope"; -import { CheckBoxProps, IndicatorProps, LabelProps } from "../../type/common/checkbox"; -import { getCustomElement } from "../../utils/common/compound"; -import styled from "styled-components"; - -const DefaultIndocator = styled.input<{ isChecked: boolean }>``; - -const DefaultLabel = styled.label<{ isChecked: boolean }>``; +import styled from 'styled-components'; +import { createContext, PropsWithChildren, ReactElement, useState } from 'react'; +import { useContextScope } from '../../hooks/common/useContextScope'; +import { CheckBoxProps, IndicatorProps, LabelProps } from '../../type/common/checkbox'; +import { getCustomElement } from '../../utils/common/compound'; type CheckBoxContextType = { isChecked: boolean; @@ -17,7 +13,7 @@ type CheckBoxContextType = { const CheckBoxContext = createContext({ isChecked: false, check: (externalFn: any) => {}, - id: "", + id: '', }); export function CheckBoxRoot(props: PropsWithChildren) { @@ -47,7 +43,7 @@ export function Indicator(props: PropsWithChildren) { ...restProps, isChecked, onClick: check, - type: "checkbox", + type: 'checkbox', id: id, }); } @@ -66,6 +62,7 @@ export function Label(props: PropsWithChildren) { if (asChild) { return getCustomElement(children as ReactElement, { ...restProps, htmlFor: id, isChecked }); } + return ( {children} @@ -73,6 +70,10 @@ export function Label(props: PropsWithChildren) { ); } +const DefaultIndocator = styled.input<{ isChecked: boolean }>``; + +const DefaultLabel = styled.label<{ isChecked: boolean }>``; + export const CheckBox = Object.assign(CheckBoxRoot, { Indicator, Label, diff --git a/apps/desktop/src/@components/@common/filter.tsx b/apps/desktop/src/@components/@common/filter.tsx index b00294c38..8b0a6ab70 100644 --- a/apps/desktop/src/@components/@common/filter.tsx +++ b/apps/desktop/src/@components/@common/filter.tsx @@ -1,13 +1,92 @@ -import { useEffect, useState } from 'react'; -import { useNavigate, useSearchParams } from 'react-router-dom'; import styled, { css } from 'styled-components'; +import { useEffect, useState } from 'react'; +import { useLocation } from 'react-router-dom'; import { TrackSearchingFalseIc, TrackSearchingTrueIc } from '../../assets'; -import { CategoryId, EventCategoryId } from '../../core/common/categories'; -import { EventUpperCategoryType, UpperCategoryType } from '../../type/common/category'; +import { EventCategoryId } from '../../core/common/categories'; +import { EventUpperCategoryType } from '../../type/common/category'; import { PageType } from '../../type/common/pageType'; import { getInvariantObjectKeys, invariantOf } from '../../utils/common/invarientType'; -import { updateQueryParams } from '../../utils/common/queryString'; import { CheckBox } from './checkBox'; +import QueryString from 'qs'; +import { useRouter } from '../../hooks/common/useRouter'; +import { STATIC_ROUTES } from '../../core/common/routes'; + +interface FilterProps { + pageType: PageType; +} + +export default function Filter(props: FilterProps) { + const { pageType } = props; + const { categ } = QueryString.parse(useLocation().search, { + ignoreQueryPrefix: true, + }); + const initialCateg = typeof categ === 'string' ? new Set([categ]) : new Set(categ as string[]); + const [selectedCategory, setSelectedCategory] = useState>(initialCateg); + const [trackSearch, setTrackSearch] = useState(false); + const router = useRouter(); + + function selectCategory(category: EventUpperCategoryType) { + const tempSelectedCategory = new Set(selectedCategory); + const categoryId = EventCategoryId[category]; + + tempSelectedCategory.has(categoryId) + ? tempSelectedCategory.delete(categoryId) + : tempSelectedCategory.add(categoryId); + + setSelectedCategory(tempSelectedCategory); + } + + function toggleTrackSearching() { + trackSearch ? setTrackSearch(false) : setTrackSearch(true); + } + + useEffect(() => { + if (pageType === 'tracks') { + router.push(STATIC_ROUTES.TRACK_SEARCH, { search: { categ: Array.from(selectedCategory) } }); + } else { + router.push(STATIC_ROUTES.VOCAL_SEARCH, { search: { categ: Array.from(selectedCategory) } }); + } + }, [selectedCategory]); + + useEffect(() => { + if (pageType === 'tracks') return; + + router.push(STATIC_ROUTES.VOCAL_SEARCH, { search: { trackSearch: trackSearch } }); + }, [trackSearch]); + + return ( + + {getInvariantObjectKeys(invariantOf(EventCategoryId)).map((category) => { + return ( + selectCategory(category)} + key={category} + defaultChecked={selectedCategory.has(EventCategoryId[category])}> + + + {category} + X + + + + ); + })} + {pageType === 'vocals' && ( + + + + {trackSearch ? : } + + Track Searching + + + + + )} + + ); +} const FilterWrapper = styled.section` position: fixed; @@ -119,72 +198,3 @@ const TrackSearchingLabel = styled.p<{ isChecked?: boolean }>` color: ${({ theme }) => theme.colors.sub2}; `} `; - -interface FilterProps { - pageType: PageType; -} - -export default function Filter(props: FilterProps) { - const { pageType } = props; - const navigate = useNavigate(); - const [searchParams, setSearchParams] = useSearchParams(); - - const [selectedCategory, setSelectedCategory] = useState>(new Set()); - const [trackSearch, setTrackSearch] = useState(false); - - function selectCategory(category: EventUpperCategoryType) { - const tempSelectedCategory = new Set(selectedCategory); - const categoryId = EventCategoryId[category]; - - tempSelectedCategory.has(categoryId) - ? tempSelectedCategory.delete(categoryId) - : tempSelectedCategory.add(categoryId); - - setSelectedCategory(tempSelectedCategory); - } - - function toggleTrackSearching() { - trackSearch ? setTrackSearch(false) : setTrackSearch(true); - } - - useEffect(() => { - const categString = updateQueryParams('categ', Array.from(selectedCategory)); - - navigate(categString); - }, [selectedCategory]); - - useEffect(() => { - trackSearch && searchParams.set('trackSearch', String(trackSearch)); - setSearchParams(searchParams); - navigate('?' + searchParams.toString()); - }, [trackSearch]); - - return ( - - {getInvariantObjectKeys(invariantOf(EventCategoryId)).map((category) => { - return ( - selectCategory(category)} key={category}> - - - {category} - X - - - - ); - })} - {pageType === 'vocals' && ( - - - - {trackSearch ? : } - - Track Searching - - - - - )} - - ); -} diff --git a/apps/desktop/src/@components/@common/inputContainer.tsx b/apps/desktop/src/@components/@common/form/inputContainer.tsx similarity index 90% rename from apps/desktop/src/@components/@common/inputContainer.tsx rename to apps/desktop/src/@components/@common/form/inputContainer.tsx index 8812af10c..8ea87f7e4 100644 --- a/apps/desktop/src/@components/@common/inputContainer.tsx +++ b/apps/desktop/src/@components/@common/form/inputContainer.tsx @@ -1,6 +1,6 @@ -import { PropsWithChildren } from "react"; -import styled from "styled-components"; -import HashtagWarning from "./hashtag/hashtagWarning"; +import styled from 'styled-components'; +import HashtagWarning from '../hashtag/hashtagWarning'; +import { PropsWithChildren } from 'react'; interface InputContainerProps { title: string; diff --git a/apps/desktop/src/@components/@common/hashTag.tsx b/apps/desktop/src/@components/@common/hashtag/hashTag.tsx similarity index 100% rename from apps/desktop/src/@components/@common/hashTag.tsx rename to apps/desktop/src/@components/@common/hashtag/hashTag.tsx diff --git a/apps/desktop/src/@components/@common/homeLogo.tsx b/apps/desktop/src/@components/@common/homeLogo.tsx index 3752a3dda..001e33ae3 100644 --- a/apps/desktop/src/@components/@common/homeLogo.tsx +++ b/apps/desktop/src/@components/@common/homeLogo.tsx @@ -1,16 +1,15 @@ -import { useContext } from "react"; -import { useNavigate } from "react-router-dom"; -import { PlayerContext } from "../../context/playerContext"; -import styled from "styled-components"; -import { HeaderHomeLogoIc } from "../../assets"; +import styled from 'styled-components'; +import { useNavigate } from 'react-router-dom'; +import { HeaderHomeLogoIc } from '../../assets'; +import { PlayUseContext } from '../../context/playerContext'; export default function HomeLogo() { const navigate = useNavigate(); - const { quitAudioForMovePage } = useContext(PlayerContext); + const { quitAudioForMovePage } = PlayUseContext({}); function handleMoveToHome() { quitAudioForMovePage(); - navigate("/"); + navigate('/'); } return ( diff --git a/apps/desktop/src/@components/@common/footer.tsx b/apps/desktop/src/@components/@common/layout/footer.tsx similarity index 68% rename from apps/desktop/src/@components/@common/footer.tsx rename to apps/desktop/src/@components/@common/layout/footer.tsx index 98126f56c..851b15d8a 100644 --- a/apps/desktop/src/@components/@common/footer.tsx +++ b/apps/desktop/src/@components/@common/layout/footer.tsx @@ -1,12 +1,11 @@ -import { useRecoilState } from "recoil"; -import styled, { keyframes } from "styled-components"; -import { FacebookLogoIc, InstagramLogoIc } from "../../assets"; -import bannerImg from "../../assets/image/bannerImg.png"; -import { CONVENTION_TYPE } from "../../core/common/convention/conventionType"; -import { openConventionModal } from "../../recoil/common/conventionModal"; +import styled from 'styled-components'; +import { useRecoilState } from 'recoil'; +import { FacebookLogoIc, InstagramLogoIc } from '../../../assets'; +import { CONVENTION_TYPE } from '../../../core/common/convention/conventionType'; +import { openConventionModal } from '../../../recoil/common/conventionModal'; export default function Footer() { - const [conventionModalInform, setConventionModalInform] = useRecoilState(openConventionModal); + const [, setConventionModalInform] = useRecoilState(openConventionModal); function openModal(policyCategory: string) { setConventionModalInform({ policy: policyCategory, isOpen: true }); @@ -14,7 +13,6 @@ export default function Footer() { return ( - {/* */} openModal(CONVENTION_TYPE.PERSONAL)}> 개인정보처리방침 @@ -54,24 +52,6 @@ const FooterContainer = styled.footer` background-color: black; `; -const LinearFlow = keyframes` - 0% {background-position : 0rem;} - 100% { background-position : -192rem}; - -`; - -const Banner = styled.div` - height: 6.2rem; - background-color: black; - margin-bottom: 5.6rem; - - /* margin-top: 3.1rem; */ - background: url(${bannerImg}) 0 center/192rem repeat-x; - -webkit-animation: ${LinearFlow} 15s infinite linear; - -moz-animation: ${LinearFlow} 15s infinite linear; - -o-animation: ${LinearFlow} 15s infinite linear; -`; - const FooterTextWrapper = styled.div` display: flex; justify-content: center; diff --git a/apps/desktop/src/@components/@common/header.tsx b/apps/desktop/src/@components/@common/layout/header.tsx similarity index 100% rename from apps/desktop/src/@components/@common/header.tsx rename to apps/desktop/src/@components/@common/layout/header.tsx diff --git a/apps/desktop/src/@components/@common/Layout/index.tsx b/apps/desktop/src/@components/@common/layout/layout.tsx similarity index 100% rename from apps/desktop/src/@components/@common/Layout/index.tsx rename to apps/desktop/src/@components/@common/layout/layout.tsx diff --git a/apps/desktop/src/@components/@common/styledComponents.ts b/apps/desktop/src/@components/@common/layout/styledComponents.ts similarity index 100% rename from apps/desktop/src/@components/@common/styledComponents.ts rename to apps/desktop/src/@components/@common/layout/styledComponents.ts diff --git a/apps/desktop/src/@components/@common/conventionModal.tsx b/apps/desktop/src/@components/@common/modal/conventionModal.tsx similarity index 86% rename from apps/desktop/src/@components/@common/conventionModal.tsx rename to apps/desktop/src/@components/@common/modal/conventionModal.tsx index 19cd8e133..6e3128564 100644 --- a/apps/desktop/src/@components/@common/conventionModal.tsx +++ b/apps/desktop/src/@components/@common/modal/conventionModal.tsx @@ -1,13 +1,13 @@ -import styled from "styled-components"; -import { SignUpModalXIc } from "../../assets"; -import useConventionModal from "../../hooks/common/useConventionModal"; -import { checkConventionType } from "../../utils/common/convention/checkConventionType"; +import styled from 'styled-components'; +import useConventionModal from '../../../hooks/common/useConventionModal'; +import { SignUpModalXIc } from '../../../assets'; +import { checkConventionType } from '../../../utils/common/convention/checkConventionType'; export default function ConventionModal() { - const { conventionModalInform, showConventionModal, closeModal } = useConventionModal(); + const { conventionModalInform, closeModal } = useConventionModal(); function isIntroNotNull() { - return checkConventionType(conventionModalInform?.policy)?.INTRO !== ""; + return checkConventionType(conventionModalInform?.policy)?.INTRO !== ''; } return ( @@ -86,7 +86,7 @@ const Title = styled.h1` const Intro = styled.p<{ intro: boolean }>` padding-bottom: ${({ intro }) => (intro ? 2.4 : 0)}rem; - border-bottom: 0.1rem solid ${({ theme, intro }) => (intro ? theme.colors.gray3 : "transparent")}; + border-bottom: 0.1rem solid ${({ theme, intro }) => (intro ? theme.colors.gray3 : 'transparent')}; ${({ theme }) => theme.fonts.typography_intro} color: ${({ theme }) => theme.colors.white}; diff --git a/apps/desktop/src/@components/@common/player.tsx b/apps/desktop/src/@components/@common/player.tsx index 5ff0c1a6e..c17b5a7c5 100644 --- a/apps/desktop/src/@components/@common/player.tsx +++ b/apps/desktop/src/@components/@common/player.tsx @@ -1,9 +1,101 @@ -import { useContext, useEffect } from "react"; -import styled from "styled-components"; -import { PlayerPlayIc, PlayerQuitIc, PlayerStopIc } from "../../assets"; -import { PlayerContext } from "../../context/playerContext"; -import useControlPlayer from "../../hooks/common/useControlPlayer"; -import { CommentsPlayerContext } from "../trackPost"; +import styled from 'styled-components'; +import useControlPlayer from '../../hooks/common/useControlPlayer'; +import { useEffect } from 'react'; +import { PlayerPlayIc, PlayerQuitIc, PlayerStopIc } from '../../assets'; +import { PlayUseContext } from '../../context/playerContext'; + +interface PlayerProps { + scope?: string; +} + +export default function Player({ scope }: PlayerProps) { + const { + playAudio, + stopAudio, + quitAudio, + closeAudioPlayer, + playContextState, + stopContextState, + showPlayer, + contextPlaying, + audio, + playerInfo, + } = PlayUseContext({ scope: scope }); + + const { + progress, + isPlaybarHovered, + playBar, + currentTimeText, + totalTimetext, + controlAudio, + downMouse, + upMouse, + moveAudio, + hoverPlaybar, + detachPlyabar, + } = useControlPlayer(audio, contextPlaying); + + window.addEventListener('popstate', quit); + + function play() { + playContextState(); + playAudio(); + } + + function pause() { + stopContextState(); + stopAudio(); + } + + function quit() { + quitAudio(); + closeAudioPlayer(); + } + + useEffect(() => { + if (!currentTimeText || !totalTimetext) return; + + if (currentTimeText === totalTimetext) { + stopContextState(); + } + }, [currentTimeText]); + + return showPlayer ? ( + + + + + + + + + + + + {playerInfo?.title} + {playerInfo?.userName} + {contextPlaying ? : } + + {currentTimeText} + + + {totalTimetext} + + + + + + ) : null; +} const PlayerContainer = styled.section` position: fixed; @@ -64,7 +156,7 @@ const Pointer = styled.div<{ progress: number; isActive: boolean }>` pointer-events: none; - display: ${({ isActive }) => !isActive && "none"}; + display: ${({ isActive }) => !isActive && 'none'}; `; const PlayerBarWrapper = styled.div<{ isActive: boolean }>` @@ -143,94 +235,3 @@ const QuitIcon = styled(PlayerQuitIc)` pointer-events: auto; `; - -interface PlayerProps { - comment?: boolean; -} - -export default function Player({ comment }: PlayerProps) { - const { - playAudio, - stopAudio, - quitAudio, - closeAudioPlayer, - playContextState, - stopContextState, - showPlayer, - contextPlaying, - audio, - playerInfo, - } = useContext(comment ? CommentsPlayerContext : PlayerContext); - - const { - progress, - isPlaybarHovered, - playBar, - currentTimeText, - totalTimetext, - controlAudio, - downMouse, - upMouse, - moveAudio, - hoverPlaybar, - detachPlyabar, - } = useControlPlayer(audio, contextPlaying); - - window.addEventListener("popstate", quit); - - function play() { - playContextState(); - playAudio(); - } - - function pause() { - stopContextState(); - stopAudio(); - } - - function quit() { - quitAudio(); - closeAudioPlayer(); - } - - useEffect(() => { - if (currentTimeText === totalTimetext) { - stopContextState(); - } - }, [currentTimeText]); - - return showPlayer ? ( - - - - - - - - - - - - {playerInfo?.title} - {playerInfo?.userName} - {contextPlaying ? : } - - {currentTimeText} - - - {totalTimetext} - - - - - - ) : null; -} diff --git a/apps/desktop/src/@components/@common/selectBox.tsx b/apps/desktop/src/@components/@common/selectBox.tsx index fcb4f0cf6..212204e2a 100644 --- a/apps/desktop/src/@components/@common/selectBox.tsx +++ b/apps/desktop/src/@components/@common/selectBox.tsx @@ -1,6 +1,7 @@ -import { PropsWithChildren, ReactElement } from "react"; -import { useContextScope } from "../../hooks/common/useContextScope"; -import { combineStates, getCustomElement } from "../../utils/common/compound"; +import styled from 'styled-components'; +import { PropsWithChildren, ReactElement } from 'react'; +import { useContextScope } from '../../hooks/common/useContextScope'; +import { combineStates, getCustomElement } from '../../utils/common/compound'; import { DescriptionProps, externalStateType, @@ -11,37 +12,10 @@ import { SelectBoxProps, SelectContextType, TriggerProps, -} from "../../type/common/select"; -import { useSelect } from "../../hooks/common/useSelect"; -import { SelectContext } from "../../context/selectContext"; -import styled from "styled-components"; +} from '../../type/common/select'; +import { useSelect } from '../../hooks/common/useSelect'; +import { SelectContext } from '../../context/selectContext'; -const DefaultLabel = styled.div` - ${({ theme }) => theme.fonts.body1} -`; - -const DefaultDescription = styled.div` - ${({ theme }) => theme.fonts.body1} -`; - -const DefaultTrigger = styled.div` - width: 2rem; - height: 2rem; -`; - -const DefaultIndicator = styled.div<{ isSelected: boolean }>` - width: 0.2rem; - height: 0.2rem; -`; - -const DefaultOptionGroup = styled.div``; - -const DefaultOption = styled.div<{ isSelected: boolean }>` - width: 8rem; - height: 2rem; -`; - -// select컴포넌트가 context를 공유할 수 있게 하는 provider컴포넌트 export const SelectBox = (props: PropsWithChildren>) => { const { children, defaultOpen, externalSelectState } = props; const { @@ -58,7 +32,6 @@ export const SelectBox = (props: PropsWithChildren) => { const { asChild = false, children, ...restProps } = props; @@ -68,7 +41,6 @@ export const Label = (props: PropsWithChildren) => { return {children}; }; -// select컴포넌트에 대한 설명 export const Description = (props: PropsWithChildren) => { const { asChild = false, children, ...restProps } = props; @@ -78,7 +50,6 @@ export const Description = (props: PropsWithChildren) => { return {children}; }; -// 클릭하면 selectBox를 보여줄 수 있는 trigger 버튼 export const Trigger = (props: PropsWithChildren) => { const { asChild = false, children, ...restProps } = props; const { toggleBoxOpen } = useContextScope(SelectContext); @@ -92,7 +63,6 @@ export const Trigger = (props: PropsWithChildren) => { return {children}; }; -// Option들을 담는 컨테이너 컴포넌트 export const OptionGroup = (props: PropsWithChildren) => { const { asChild = false, children, ...restProps } = props; const { isSelecBoxOpen } = useContextScope(SelectContext); @@ -103,7 +73,6 @@ export const OptionGroup = (props: PropsWithChildren) => { return isSelecBoxOpen ? {children} : null; }; -// Option이 선택되었는지 나타내는 indicator export const Indicator = (props: PropsWithChildren) => { const { asChild = false, children, ...restProps } = props; const { selectedId } = useContextScope(SelectContext); @@ -115,7 +84,6 @@ export const Indicator = (props: PropsWithChildren) => { return {children}; }; -// select의 각 Option export const Option = (props: PropsWithChildren) => { const { asChild = false, children, ...restProps } = props; const { selectOption, selectedId } = useContextScope(SelectContext); @@ -147,6 +115,31 @@ export const Option = (props: PropsWithChildren) => { ); }; +const DefaultLabel = styled.div` + ${({ theme }) => theme.fonts.body1} +`; + +const DefaultDescription = styled.div` + ${({ theme }) => theme.fonts.body1} +`; + +const DefaultTrigger = styled.div` + width: 2rem; + height: 2rem; +`; + +const DefaultIndicator = styled.div<{ isSelected: boolean }>` + width: 0.2rem; + height: 0.2rem; +`; + +const DefaultOptionGroup = styled.div``; + +const DefaultOption = styled.div<{ isSelected: boolean }>` + width: 8rem; + height: 2rem; +`; + export const Select = Object.assign(SelectBox, { Label, Description, diff --git a/apps/desktop/src/@components/@common/switch.tsx b/apps/desktop/src/@components/@common/switch.tsx index 89d29b9c6..847889404 100644 --- a/apps/desktop/src/@components/@common/switch.tsx +++ b/apps/desktop/src/@components/@common/switch.tsx @@ -1,7 +1,45 @@ +import styled, { css, keyframes } from 'styled-components'; import { PropsWithChildren, useContext, useState } from 'react'; import { SwitchContext } from '../../context/switchContext'; import { LabelProps, RootProps, SwitchProps, ThumbProps } from '../../type/common/switch'; -import styled, { css, keyframes } from 'styled-components'; + +function SwitchBox(props: PropsWithChildren) { + const { externalState, children } = props; + const [currentThumb, setCurrentThumb] = useState<'on' | 'off'>('off'); + + const combineState = (externalFn: any, internalFn: any) => { + return () => { + externalFn?.(); + internalFn?.(); + }; + }; + + function internalSwitchThumb() { + currentThumb === 'on' ? setCurrentThumb('off') : setCurrentThumb('on'); + } + const switchThumb = combineState(externalState, internalSwitchThumb); + return {children}; +} + +function Label(props: LabelProps) { + const { onLabel, offLabel } = props; + const { currentThumb } = useContext(SwitchContext); + + return {currentThumb === 'on' ? onLabel : offLabel}; +} + +function Root(props: PropsWithChildren) { + const { children } = props; + const { currentThumb } = useContext(SwitchContext); + + return {children}; +} + +function Thumb(props: ThumbProps) { + const { switchThumb, currentThumb } = useContext(SwitchContext); + + return ; +} const DefaultLabel = styled.p` ${({ theme }) => theme.fonts.hashtag} @@ -70,44 +108,6 @@ const DefaultThumb = styled.div<{ switchState: 'on' | 'off' }>` `} `; -function SwitchBox(props: PropsWithChildren) { - const { externalState, children } = props; - const [currentThumb, setCurrentThumb] = useState<'on' | 'off'>('off'); - - const combineState = (externalFn: any, internalFn: any) => { - return () => { - externalFn?.(); - internalFn?.(); - }; - }; - - function internalSwitchThumb() { - currentThumb === 'on' ? setCurrentThumb('off') : setCurrentThumb('on'); - } - const switchThumb = combineState(externalState, internalSwitchThumb); - return {children}; -} - -function Label(props: LabelProps) { - const { onLabel, offLabel } = props; - const { currentThumb } = useContext(SwitchContext); - - return {currentThumb === 'on' ? onLabel : offLabel}; -} - -function Root(props: PropsWithChildren) { - const { children } = props; - const { currentThumb } = useContext(SwitchContext); - - return {children}; -} - -function Thumb(props: ThumbProps) { - const { switchThumb, currentThumb } = useContext(SwitchContext); - - return ; -} - export const Switch = Object.assign(SwitchBox, { Label, Root, diff --git a/apps/desktop/src/@components/about/aboutMain.tsx b/apps/desktop/src/@components/about/aboutMain.tsx deleted file mode 100644 index 7f4677900..000000000 --- a/apps/desktop/src/@components/about/aboutMain.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import styled from "styled-components"; -import mainSectionBackgroundImg from "../../assets/image/mainSectionBackgroundImg.png"; - -interface AboutMainProps { - handleMoveAboutSection: () => void; - handleMoveHowToSection: () => void; -} - -export default function AboutMain(props: AboutMainProps) { - const { handleMoveAboutSection, handleMoveHowToSection } = props; - return ( - - - DISCOVER YOUR LIMITLESS TRACK - Limitless chance and inspiration for Musicians - - - About us - How to use - - - - - ); -} - -const Styled = { - MainSection: styled.section` - width: 100%; - height: 143rem; - - background: url(${mainSectionBackgroundImg}); - background-repeat: no-repeat; - background-size: cover; - `, - - MainSectionWrapper: styled.div` - position: absolute; - - width: 100%; - padding: 0 10rem; - margin: auto; - `, - - TapMenuWrapper: styled.ul` - display: flex; - justify-content: center; - - width: 100%; - - margin-top: 57.6rem; - - color: ${({ theme }) => theme.colors.white}; - ${({ theme }) => theme.fonts.alexandria_text30}; - `, - - TapMenu: styled.li` - padding: 3rem 8rem; - - cursor: pointer; - - :hover { - color: ${({ theme }) => theme.colors.main}; - } - `, - - DivisionLine: styled.hr` - width: 100%; - - border: 0.1rem solid ${({ theme }) => theme.colors.white}; - - border-image: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, #fff 50.02%, rgba(255, 255, 255, 0) 100%); - border-image-slice: 1; - `, - - HeadingText: styled.h1` - color: ${({ theme }) => theme.colors.white}; - ${({ theme }) => theme.fonts.alexandria_heading98}; - - margin: 38.8rem 0 2rem; - - text-align: center; - - white-space: pre-line; - `, - - SubDescriptionText: styled.p` - color: ${({ theme }) => theme.colors.white}; - ${({ theme }) => theme.fonts.pretendard_text25}; - - float: right; - - letter-spacing: -0.025rem; - - white-space: pre-line; - `, -}; diff --git a/apps/desktop/src/@components/about/aboutUs.tsx b/apps/desktop/src/@components/about/aboutUs.tsx deleted file mode 100644 index 35832169a..000000000 --- a/apps/desktop/src/@components/about/aboutUs.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import styled from "styled-components"; -import aboutBackgroundImg from "../../assets/image/aboutBackgroundImg.png"; -import laptopImg from "../../assets/image/laptopImg.png"; - -interface AboutUsProps { - scrollRef: React.RefObject; -} - -export default function AboutUs(props: AboutUsProps) { - const { scrollRef } = props; - - return ( - - - - { - "예술은 창조에서 시작되고, 창조는 영감에서 비롯됩니다.\n머릿속에서 떠다니는 음악적 아이디어를 자유롭게 표현할 수 있도록\n활발한 소통의 장을 마련하는 것이 우리의 목표입니다." - } - - - { - "Art begins with creation, and creation is born from inspiration.\nOur goal is to provide a vibrant platform for you to freely express the musical ideas floating in your mind, where you can bring fleeting musical concepts to life." - } - - - - - - - - { - "Track-1은 뮤지션의 잠재력을 펼치는 데에 집중합니다.\n번뜩이는 악상이 하나의 예술작품으로 구현되는 과정을 더욱 원활히 하고,\n보다 많은 예술가와 함께할 수 있도록 협업 기회를 제공합니다." - } - - - { - "Track-1 focuses on unleashing the potential of musicians.\nWe aim to streamline the process of transforming a brilliant melody into a work of art and offer more collaborative opportunities by bringing artists together." - } - - {"Discover your\nLimitless\nChance and inspiration"} - - - - - { - "뮤직 트랙에 담긴 영감과 잠재력이 무한하듯, 눈 앞에 펼쳐진 가능성의 트랙도 끝이 없습니다.\n작업실에서의 흥얼거림이 세상을 흔드는 파동이 될 수 있도록,\n잠재된 수많은 트랙을 발견하고 세상 밖으로 꺼낼 수 있도록, 우리는 준비하고 기다립니다." - } - - - { - "Just as the inspiration and potential within music tracks seem limitless, so does the endless potential of the tracks waiting before you.\nAs the hums in your studio may create waves that shake the world,\nwe are ready and waiting to help you discover and share countless hidden tracks with the world." - } - - - - ); -} - -const Styled = { - AboutSection: styled.section` - width: 100%; - - margin-top: -20.3rem; - - padding-top: 14.3rem; - `, - - AboutSectionWrapper: styled.div` - width: 100%; - - padding: 0 10rem; - - &.last_wrapper { - margin-top: 75.3rem; - } - `, - - AboutBackgroundImageSectionWrapper: styled.div` - position: relative; - - width: 100%; - height: 94.4rem; - - padding: 0 10rem; - - padding-top: 16.7rem; - - background: url(${aboutBackgroundImg}); - background-repeat: no-repeat; - background-size: cover; - `, - - TapMenuWrapper: styled.ul` - display: flex; - justify-content: center; - - width: 100%; - - margin-top: 57.6rem; - - color: ${({ theme }) => theme.colors.white}; - ${({ theme }) => theme.fonts.alexandria_text30}; - `, - - TapMenu: styled.li` - padding: 3rem 8rem; - - cursor: pointer; - - :hover { - color: ${({ theme }) => theme.colors.main}; - } - `, - - LaptopImage: styled.img` - width: 100%; - - margin: 6.4rem 0 6.5rem; - `, - - HeadingText: styled.h1` - color: ${({ theme }) => theme.colors.white}; - ${({ theme }) => theme.fonts.alexandria_heading98}; - - margin: 38.8rem 0 2rem; - - white-space: pre-line; - - &.text-center { - text-align: center; - } - - &.purple { - position: absolute; - top: 85.8rem; - margin: 0; - color: ${({ theme }) => theme.colors.main}; - ${({ theme }) => theme.fonts.alexandria_text148}; - - text-align: right; - } - `, - - SubDescriptionText: styled.p` - color: ${({ theme }) => theme.colors.gray3}; - ${({ theme }) => theme.fonts.pretendard_text25}; - - letter-spacing: -0.025rem; - - white-space: pre-line; - - &.description { - margin-top: 5rem; - - color: ${({ theme }) => theme.colors.gray2}; - font-weight: 500; - line-height: 4.375rem; - letter-spacing: -0.25px; - } - - &.text-center { - text-align: center; - } - `, - - AboutDescriptionText: styled.h2` - color: ${({ theme }) => theme.colors.white}; - ${({ theme }) => theme.fonts.pretendard_text40}; - - margin-bottom: 6.4rem; - - white-space: pre-line; - - &.text-center { - text-align: center; - } - `, -}; diff --git a/apps/desktop/src/@components/about/howToUse.tsx b/apps/desktop/src/@components/about/howToUse.tsx deleted file mode 100644 index 8289c5fd4..000000000 --- a/apps/desktop/src/@components/about/howToUse.tsx +++ /dev/null @@ -1,229 +0,0 @@ -import styled from "styled-components"; -import commentExampleImg from "../../assets/image/commentExampleImg.png"; -import vocalSearchExampleImg from "../../assets/image/vocalSearchExampleImg.png"; - -interface HowToUseProps { - scrollRef: React.RefObject; -} - -export default function HowToUse(props: HowToUseProps) { - const { scrollRef } = props; - return ( - - - - - {"Collaboration\nPlatform\nfor Musicians"} - - {"User Guideline"} - - - - - { - "Track-1은 보컬과 프로듀서가 서로 협업할 뮤지션을 찾을 수 있는 플랫폼입니다.\n원하는 느낌의 뮤지션을 편리하게 탐색할 수 있고,\n데모 작업을 통해 직관적으로 잘 맞는 뮤지션과 컨택할 수 있습니다.\nTrack-1에서 무궁무진한 협업의 기회를 얻어가세요." - } - - - { - "Track-1 is a platform where vocalists and producers\ncan find fellow musicians to collaborate with.\nYou can conveniently explore musicians with the desired vibe and\neasily get in touch with those who are a perfect match through demo work.\nDiscover endless opportunities for collaboration on Track-1." - } - - - - - - - - - - - - {"Listen for yourself"} - - { - "프로듀서가 업로드한 스케치곡에 보컬이 자신의 목소리를 입혀 댓글을 달 수 있어요.\n내 곡에 가장 잘 맞는 보컬을 직관적으로 찾아보세요." - } - - - - { - "Producers upload demo tracks.\nVocalists can add their voice to the demo track they like and leave comments." - } - - - - - {} - - - {"Optimized\nfor exploration"} - - { - "음악 장르를 필터링하고, 다른 뮤지션의 대표곡을 들어볼 수 있어요.\n원하는 느낌의 뮤지션을 빠르고 편리하게 찾아보세요!" - } - - - {"Easily discover talented musicians who complement your style and sound."} - - - - - - - - ); -} - -const Styled = { - HowtoSection: styled.section` - width: 100%; - - margin-top: 14.3rem; - - padding-top: 11.7rem; - `, - - HeadingText: styled.h1` - color: ${({ theme }) => theme.colors.white}; - ${({ theme }) => theme.fonts.alexandria_heading98}; - - margin: 38.8rem 0 2rem; - - white-space: pre-line; - - &.text-center { - text-align: center; - } - - &.purple { - margin: 32.3rem 0; - - color: ${({ theme }) => theme.colors.main}; - ${({ theme }) => theme.fonts.alexandria_text148}; - - text-align: right; - } - - &.howTo_100 { - margin: 0; - margin-bottom: 67.5rem; - - color: ${({ theme }) => theme.colors.white}; - ${({ theme }) => theme.fonts.alexandria_heading100}; - - background: linear-gradient(109deg, #fff 40.49%, rgba(59, 60, 63, 0) 110.64%); - background-clip: text; - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - } - - &.howTo_90 { - margin: 0; - margin-bottom: 10rem; - - color: ${({ theme }) => theme.colors.white}; - ${({ theme }) => theme.fonts.alexandria_heading100}; - } - `, - - SubDescriptionText: styled.p` - color: ${({ theme }) => theme.colors.gray3}; - ${({ theme }) => theme.fonts.pretendard_text25}; - - letter-spacing: -0.025rem; - - white-space: pre-line; - - &.main-section { - color: ${({ theme }) => theme.colors.white}; - float: right; - } - - &.howTo-section { - color: ${({ theme }) => theme.colors.white}; - font-weight: 500; - line-height: 4.5rem; - } - - &.description { - margin-top: 5rem; - - color: ${({ theme }) => theme.colors.gray2}; - font-weight: 500; - line-height: 4.375rem; - letter-spacing: -0.25px; - } - - &.text-center { - text-align: center; - } - `, - - HowToSectionWrapper: styled.div` - padding: 0 10rem; - `, - - HowToTextWrapper: styled.div` - display: flex; - - width: 100%; - height: 100%; - - display: flex; - `, - - HowToLeftTextWrapper: styled.div` - width: 87.1rem; - - h1 { - &:last-child { - margin: 0; - } - } - `, - - HowToRightTextWrapper: styled.div` - width: calc(100% - 87.1rem); - - &.howTo_100 { - padding-top: 35.1rem; - } - `, - - CommentExampleImage: styled.img` - width: 100%; - - margin: 10rem 0 25rem; - `, - - VocalSearchExampleImage: styled.img` - width: 100%; - - margin: 10rem 0 20rem; - `, - - Video: styled.video` - width: 192rem; - height: 108rem; - - margin: 10rem 0 35rem; - - animation: showVideo 2s ease-out; - - @keyframes showVideo { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } - } - `, -}; diff --git a/apps/desktop/src/@components/about/index.tsx b/apps/desktop/src/@components/about/index.tsx deleted file mode 100644 index 7e75a1993..000000000 --- a/apps/desktop/src/@components/about/index.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import styled from 'styled-components'; -import Footer from '../@common/footer'; -import { useEffect, useRef } from 'react'; -import AboutUs from './aboutUs'; -import HowToUse from './howToUse'; -import AboutMain from './aboutMain'; -import MainHeader from '../main/mainHeader'; - -export default function About() { - const aboutSectionRef = useRef(null); - const howToSectionRef = useRef(null); - - useEffect(() => { - window.scrollTo(0, 0); - }, []); - - function handleMoveAboutSection() { - aboutSectionRef.current?.scrollIntoView({ behavior: 'smooth' }); - } - - function handleMoveHowToSection() { - howToSectionRef.current?.scrollIntoView({ behavior: 'smooth' }); - } - - return ( - <> - - {/* Main */} - - {/* About us */} - - {/* How to use */} - - -