diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bae2d7a8..96e2ea55 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -484,6 +484,9 @@ importers: dotenv: specifier: ^17.2.0 version: 17.2.3 + framer-motion: + specifier: ^12.42.2 + version: 12.42.2(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) html2canvas: specifier: ^1.4.1 version: 1.4.1 @@ -2971,36 +2974,42 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==} @@ -3077,56 +3086,67 @@ packages: resolution: {integrity: sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.52.4': resolution: {integrity: sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.52.4': resolution: {integrity: sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.52.4': resolution: {integrity: sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.52.4': resolution: {integrity: sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-gnu@4.52.4': resolution: {integrity: sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.52.4': resolution: {integrity: sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.52.4': resolution: {integrity: sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.52.4': resolution: {integrity: sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.52.4': resolution: {integrity: sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.52.4': resolution: {integrity: sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openharmony-arm64@4.52.4': resolution: {integrity: sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==} @@ -3493,24 +3513,28 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [glibc] '@swc/core-linux-arm64-musl@1.14.0': resolution: {integrity: sha512-uofpVoPCEUjYIv454ZEZ3sLgMD17nIwlz2z7bsn7rl301Kt/01umFA7MscUovFfAK2IRGck6XB+uulMu6aFhKQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [musl] '@swc/core-linux-x64-gnu@1.14.0': resolution: {integrity: sha512-quTTx1Olm05fBfv66DEBuOsOgqdypnZ/1Bh3yGXWY7ANLFeeRpCDZpljD9BSjdsNdPOlwJmEUZXMHtGm3v1TZQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [glibc] '@swc/core-linux-x64-musl@1.14.0': resolution: {integrity: sha512-caaNAu+aIqT8seLtCf08i8C3/UC5ttQujUjejhMcuS1/LoCKtNiUs4VekJd2UGt+pyuuSrQ6dKl8CbCfWvWeXw==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [musl] '@swc/core-win32-arm64-msvc@1.14.0': resolution: {integrity: sha512-EeW3jFlT3YNckJ6V/JnTfGcX7UHGyh6/AiCPopZ1HNaGiXVCKHPpVQZicmtyr/UpqxCXLrTgjHOvyMke7YN26A==} @@ -4189,6 +4213,7 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@unrs/resolver-binding-android-arm-eabi@1.11.1': resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} @@ -4229,41 +4254,49 @@ packages: resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-arm64-musl@1.11.1': resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} cpu: [arm64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} cpu: [riscv64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} cpu: [riscv64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} cpu: [s390x] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-gnu@1.11.1': resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} cpu: [x64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-musl@1.11.1': resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} cpu: [x64] os: [linux] + libc: [musl] '@unrs/resolver-binding-wasm32-wasi@1.11.1': resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} @@ -6312,6 +6345,20 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} + framer-motion@12.42.2: + resolution: {integrity: sha512-5XY9luDiu0oHfHBjpDthFMh0ES+122w6p/papSJBweMkO8Sn+PW2QaEgRblQBpWFnuvZS5qvarpt/hO2pjGmnw==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + freeport-async@2.0.0: resolution: {integrity: sha512-K7od3Uw45AJg00XUmy15+Hae2hOcgKcmN3/EF6Y7i01O0gaqiRx8sUSpsb9+BRNL8RPBrhzPsVfy8q9ADlJuWQ==} engines: {node: '>=8'} @@ -7344,48 +7391,56 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-gnu@1.32.0: resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.30.2: resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.30.2: resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.30.2: resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.30.2: resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} @@ -7763,6 +7818,12 @@ packages: engines: {node: '>=10'} hasBin: true + motion-dom@12.42.2: + resolution: {integrity: sha512-5gIMWLp/PycBtJRJWRgjxke5n8dlvkSn2DrYW+tr3XcqAZY1xZh6BJyooJXCM8wdfM7wfMjkBJNLge1CKPUIRA==} + + motion-utils@12.39.0: + resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -9353,6 +9414,7 @@ packages: tsconfck@3.1.6: resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} engines: {node: ^18 || >=20} + deprecated: unmaintained hasBin: true peerDependencies: typescript: ^5.0.0 @@ -17199,6 +17261,16 @@ snapshots: forwarded@0.2.0: {} + framer-motion@12.42.2(@emotion/is-prop-valid@1.4.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + motion-dom: 12.42.2 + motion-utils: 12.39.0 + tslib: 2.8.1 + optionalDependencies: + '@emotion/is-prop-valid': 1.4.0 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + freeport-async@2.0.0: {} fresh@0.5.2: {} @@ -19048,6 +19120,12 @@ snapshots: mkdirp@1.0.4: {} + motion-dom@12.42.2: + dependencies: + motion-utils: 12.39.0 + + motion-utils@12.39.0: {} + ms@2.0.0: {} ms@2.1.3: {} diff --git a/web/package.json b/web/package.json index e6385eb8..ebbe4972 100644 --- a/web/package.json +++ b/web/package.json @@ -95,6 +95,7 @@ "@tanstack/react-router": "^1.128.3", "@tanstack/react-router-devtools": "^1.128.3", "dotenv": "^17.2.0", + "framer-motion": "^12.42.2", "html2canvas": "^1.4.1", "react": "^19.1.0", "react-dom": "^19.1.0", diff --git a/web/src/components/RouteTransition/RouteTransition.tsx b/web/src/components/RouteTransition/RouteTransition.tsx new file mode 100644 index 00000000..8893d494 --- /dev/null +++ b/web/src/components/RouteTransition/RouteTransition.tsx @@ -0,0 +1,161 @@ +import styled from '@emotion/styled'; +import { useRouterState } from '@tanstack/react-router'; +import { motion, useReducedMotion } from 'framer-motion'; +import { useLayoutEffect, useRef, useState } from 'react'; +import { useDevice } from '@/hooks/useDevice'; +import type { ReactNode } from 'react'; + +type NavigationDirection = 'push' | 'pop'; + +const DETAIL_PATH_PATTERNS = [ + /^\/articles\/(previous\/)?[^/]+$/, + /^\/newsletters\/[^/]+$/, + /^\/challenge\/[^/]+\/(landing|dashboard|daily|comments|review|certification)$/, +]; + +const getChallengeId = (pathname: string) => + pathname.match(/^\/challenge\/([^/]+)\//)?.[1]; + +const isDetailPath = (pathname: string) => + DETAIL_PATH_PATTERNS.some((pattern) => pattern.test(pathname)); + +interface RouteTransitionProps { + children: ReactNode; +} + +interface PageSnapshot { + html: string; + scrollY: number; +} + +const RouteTransition = ({ children }: RouteTransitionProps) => { + const device = useDevice(); + const shouldReduceMotion = useReducedMotion(); + const location = useRouterState({ select: (state) => state.location }); + const pageRef = useRef(null); + const previousLocationRef = useRef(location); + const previousPageRef = useRef({ html: '', scrollY: 0 }); + const [, setTransitionFinishedKey] = useState(); + const locationKey = location.state.__TSR_key ?? location.href; + const previousLocation = previousLocationRef.current; + const previousLocationKey = + previousLocation.state.__TSR_key ?? previousLocation.href; + const hasLocationChanged = previousLocationKey !== locationKey; + const direction: NavigationDirection = + location.state.__TSR_index < previousLocation.state.__TSR_index + ? 'pop' + : 'push'; + const currentChallengeId = getChallengeId(location.pathname); + const previousChallengeId = getChallengeId(previousLocation.pathname); + const isSameChallenge = + !!currentChallengeId && currentChallengeId === previousChallengeId; + const isTransitioning = + hasLocationChanged && + device === 'mobile' && + !shouldReduceMotion && + !isSameChallenge && + (isDetailPath(location.pathname) || + isDetailPath(previousLocation.pathname)); + const snapshot = previousPageRef.current; + + useLayoutEffect(() => { + const currentPage = pageRef.current; + + if (currentPage) { + previousPageRef.current = { + html: currentPage.innerHTML, + scrollY: window.scrollY, + }; + } + previousLocationRef.current = location; + }, [location]); + + if (device !== 'mobile') return children; + + return ( + + {isTransitioning && direction === 'push' && ( + + )} + setTransitionFinishedKey(locationKey) + : undefined + } + > + {children} + + {isTransitioning && direction === 'pop' && ( + { + setTransitionFinishedKey(locationKey); + }} + dangerouslySetInnerHTML={{ __html: snapshot.html }} + /> + )} + + ); +}; + +export default RouteTransition; + +const Container = styled.div` + position: relative; + width: 100%; + min-height: 100dvh; + + background-color: ${({ theme }) => theme.colors.white}; + + overflow-x: clip; +`; + +const AnimatedPage = styled(motion.div)` + position: relative; + z-index: 1; + width: 100%; + min-height: 100dvh; + + background-color: ${({ theme }) => theme.colors.white}; +`; + +const SnapshotPage = styled(motion.div)<{ + $scrollY: number; + $isOverlay: boolean; +}>` + position: fixed; + top: ${({ $scrollY }) => `-${$scrollY}px`}; + right: 0; + left: 0; + z-index: ${({ $isOverlay }) => ($isOverlay ? 2 : 0)}; + min-height: 100dvh; + + background-color: ${({ theme }) => theme.colors.white}; + + pointer-events: none; +`; diff --git a/web/src/pages/my-page/components/ReadingActivityStats/MonthlyReadingCalendar.tsx b/web/src/pages/my-page/components/ReadingActivityStats/MonthlyReadingCalendar.tsx index b63f6220..ffe9f519 100644 --- a/web/src/pages/my-page/components/ReadingActivityStats/MonthlyReadingCalendar.tsx +++ b/web/src/pages/my-page/components/ReadingActivityStats/MonthlyReadingCalendar.tsx @@ -157,7 +157,6 @@ const Weekday = styled(Text)` const Divider = styled.div` height: 1px; - background-color: ${COLORS.divider}; `; @@ -168,7 +167,6 @@ const Grid = styled.div` const DayCell = styled.div` position: relative; - height: 28px; display: flex; @@ -186,7 +184,6 @@ const MostReadCircle = styled(Text)` position: absolute; top: 50%; left: 50%; - width: 32px; height: 32px; border-radius: 50%; @@ -204,7 +201,6 @@ const ReadUnderline = styled.span` position: absolute; bottom: 0; left: 50%; - width: 26px; height: 4px; border-radius: 2px; diff --git a/web/src/pages/my-page/components/ReadingActivityStats/MonthlyReportStats.tsx b/web/src/pages/my-page/components/ReadingActivityStats/MonthlyReportStats.tsx index 1d97af5c..59f2bba6 100644 --- a/web/src/pages/my-page/components/ReadingActivityStats/MonthlyReportStats.tsx +++ b/web/src/pages/my-page/components/ReadingActivityStats/MonthlyReportStats.tsx @@ -146,9 +146,8 @@ const IconBox = styled.div` height: 40px; border-radius: 10px; - flex-shrink: 0; - display: flex; + flex-shrink: 0; align-items: center; justify-content: center; @@ -191,11 +190,12 @@ const StatUnit = styled(Text)` `; const ChangePill = styled(Text)` - align-self: flex-start; padding: 6px 12px; border: 1px solid ${COLORS.pillBorder}; border-radius: 12px; + align-self: flex-start; + && { color: ${COLORS.pillText}; } @@ -249,9 +249,8 @@ const RankBadge = styled(Text)` height: 18px; border-radius: 50%; - flex-shrink: 0; - display: flex; + flex-shrink: 0; align-items: center; justify-content: center; @@ -259,12 +258,12 @@ const RankBadge = styled(Text)` `; const NewsletterName = styled(Text)` + overflow: hidden; min-width: 0; - overflow: hidden; + white-space: nowrap; text-overflow: ellipsis; - white-space: nowrap; && { color: ${COLORS.newsletterText}; @@ -273,7 +272,6 @@ const NewsletterName = styled(Text)` const NewsletterCount = styled(Text)` margin-left: auto; - flex-shrink: 0; && { diff --git a/web/src/pages/system/components/NotFoundCard.tsx b/web/src/pages/system/components/NotFoundCard.tsx index f5958af5..9edba29f 100644 --- a/web/src/pages/system/components/NotFoundCard.tsx +++ b/web/src/pages/system/components/NotFoundCard.tsx @@ -67,8 +67,8 @@ const DescriptionWrapper = styled.div` const Description = styled.p``; const GoHomeButton = styled(Button)` - margin-top: 12px; max-width: 380px; + margin-top: 12px; font: ${({ theme }) => theme.fonts.t7Bold}; `; diff --git a/web/src/routes/__root.tsx b/web/src/routes/__root.tsx index 759fc398..8240d191 100644 --- a/web/src/routes/__root.tsx +++ b/web/src/routes/__root.tsx @@ -7,6 +7,7 @@ import { Outlet, } from '@tanstack/react-router'; import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'; +import RouteTransition from '@/components/RouteTransition/RouteTransition'; import Toast from '@/components/Toast/Toast'; import { AuthProvider } from '@/contexts/AuthContext'; import { useChannelTalk } from '@/hooks/useChannelTalk'; @@ -41,7 +42,9 @@ const RootComponent = () => { - + + +