Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import FilteredLetterManage from './pages/Admin/FilteredLetter';
import FilteringManage from './pages/Admin/Filtering';
import ReportManage from './pages/Admin/Report';
import AdminRollingPaper from './pages/Admin/RollingPaper';
import AdminRoute from './layouts/AdminRoute';
import AuthCallbackPage from './pages/Auth';
import Home from './pages/Home';
import Landing from './pages/Landing';
Expand All @@ -28,12 +29,10 @@ import RollingPaperPage from './pages/RollingPaper';
import WritePage from './pages/Write';
import ShareApprovalPage from './pages/Share';
import useThemeStore from './stores/themeStore';
import { useServerSentEvents } from './hooks/useServerSentEvents';

const App = () => {
const theme = useThemeStore((state) => state.theme);
useViewport();
useServerSentEvents();

const initializeTheme = () => {
if (theme === 'dark') {
Expand Down Expand Up @@ -81,7 +80,7 @@ const App = () => {
</Route>
</Route>

<Route element={<PrivateRoute />}>
<Route element={<AdminRoute />}>
<Route path="admin" element={<AdminPage />}>
<Route path="report" element={<ReportManage />} />
<Route path="badwords" element={<FilteringManage />} />
Expand Down
Binary file removed src/assets/images/background-dark.png
Binary file not shown.
Binary file added src/assets/images/background-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/images/field-4-dark.png
Binary file not shown.
Binary file added src/assets/images/field-4-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/images/field-theme-asset-bird-dark.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/images/go-to-random-letter.png
Binary file not shown.
Binary file added src/assets/images/go-to-random-letter.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/images/home-left-mountain-dark.png
Binary file not shown.
Binary file added src/assets/images/home-left-mountain-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/images/home-left-mountain.png
Binary file not shown.
Binary file added src/assets/images/home-left-mountain.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/images/home-right-mountain-bottom.png
Binary file not shown.
Binary file added src/assets/images/home-right-mountain-bottom.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/images/home-right-mountain-top-dark.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/images/home-right-mountain-top.png
Binary file not shown.
Binary file added src/assets/images/home-right-mountain-top.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/images/landing-dark.png
Binary file not shown.
Binary file added src/assets/images/landing-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed src/assets/images/landing.png
Binary file not shown.
Binary file added src/assets/images/landing.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/components/BackgroundBottom.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import BgItem from '@/assets/images/field-4.png';
import BgItemDark from '@/assets/images/field-4-dark.png';
import BgItemDark from '@/assets/images/field-4-dark.webp';

import BackgroundImageWrapper from './BackgroundImageWrapper';
import useThemeStore from '@/stores/themeStore';
Expand Down
29 changes: 29 additions & 0 deletions src/layouts/AdminRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useEffect } from 'react';
import { useNavigate, Outlet } from 'react-router';

import useAuthStore from '@/stores/authStore';

export default function AdminRoute() {
const isLoggedIn = useAuthStore((state) => state.isLoggedIn);
const isAdmin = useAuthStore((state) => state.isAdmin);
const navigate = useNavigate();

useEffect(() => {
if (!isLoggedIn) {
navigate('/login', { replace: true });
}
if (!isAdmin) {
navigate('/', { replace: true });
}
}, [isLoggedIn, navigate]);

if (!isLoggedIn || !isAdmin) {
return null;
}

return (
<>
<Outlet />
</>
);
}
4 changes: 2 additions & 2 deletions src/layouts/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ const Header = () => {
</button>
<div className="flex items-center gap-3">
{theme === 'light' ? (
<FlareRoundedIcon className="h-6 w-6 text-white" onClick={toggleTheme} />
) : (
<DarkModeOutlinedIcon className="h-6 w-6 text-white" onClick={toggleTheme} />
) : (
<FlareRoundedIcon className="h-6 w-6 text-white" onClick={toggleTheme} />
)}
<NotificationButton />
<Link to="/mypage">
Expand Down
10 changes: 4 additions & 6 deletions src/layouts/PrivateRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
import { useEffect, useState } from 'react';
import { useEffect } from 'react';
import { useNavigate, Outlet } from 'react-router';

import useAuthStore from '@/stores/authStore';
import { useServerSentEvents } from '@/hooks/useServerSentEvents';
import Toast from '@/components/Toast';

export default function PrivateRoute() {
useServerSentEvents();
const isLoggedIn = useAuthStore((state) => state.isLoggedIn);
const navigate = useNavigate();
const [shouldRender, setShouldRender] = useState(false);

useServerSentEvents();

useEffect(() => {
if (!isLoggedIn) {
navigate('/login', { replace: true });
} else {
setShouldRender(true);
}
}, [isLoggedIn, navigate]);

if (!shouldRender) {
if (!isLoggedIn) {
return null;
}

Expand Down
17 changes: 14 additions & 3 deletions src/pages/Auth/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ const AuthCallbackPage = () => {
const logout = useAuthStore((state) => state.logout);
const setAccessToken = useAuthStore((state) => state.setAccessToken);
const setZipCode = useAuthStore((state) => state.setZipCode);
const setIsAdmin = useAuthStore((state) => state.setIsAdmin);
const navigate = useNavigate();
let accessToken = '';
let role = '';

const handleError = (error: unknown) => {
console.error('AuthCallback Error:', error);
Expand All @@ -32,8 +35,7 @@ const AuthCallbackPage = () => {

login();
if (userInfo.accessToken) setAccessToken(userInfo.accessToken);

console.log(redirectURL);
accessToken = userInfo.accessToken;

switch (redirectURL) {
case 'home':
Expand All @@ -54,14 +56,23 @@ const AuthCallbackPage = () => {
if (!newAccessToken) throw new Error('Missing new access token');

setAccessToken(newAccessToken);
accessToken = newAccessToken;
}
break;

default:
navigate('/notFound');
return;
}
navigate(redirectURL === 'onboarding' ? '/onboarding' : '/');

role = JSON.parse(atob(accessToken.split('.')[1])).role;

if (role === 'ADMIN') {
setIsAdmin();
navigate('/admin');
} else {
navigate(redirectURL === 'onboarding' ? '/onboarding' : '/');
}
} catch (error) {
handleError(error);
}
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Home/components/GoToRandomLetter.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Link } from 'react-router';

import goToRandomLetter from '@/assets/images/go-to-random-letter.png';
import goToRandomLetter from '@/assets/images/go-to-random-letter.webp';

const GoToRandomLetter = () => {
return (
Expand All @@ -10,7 +10,7 @@ const GoToRandomLetter = () => {
고민편지 보러가기
</p>
<Link to={'/letter/random'}>
<img src={goToRandomLetter} alt="go to random letter" />
<img src={goToRandomLetter} alt="go to random letter" className="h-45 translate-x-5" />
</Link>
</div>
</>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Home/components/HomeBackgroundLeft.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import homeLeftMountain from '@/assets/images/home-left-mountain.png';
import homeLeftMountainDark from '@/assets/images/home-left-mountain-dark.png';
import homeLeftMountain from '@/assets/images/home-left-mountain.webp';
import homeLeftMountainDark from '@/assets/images/home-left-mountain-dark.webp';

import BackgroundImageWrapper from '@/components/BackgroundImageWrapper';
import useThemeStore from '@/stores/themeStore';
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Home/components/HomeBackgroundRightBottom.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import homeRightMountainBottom from '@/assets/images/home-right-mountain-bottom.png';
import homeRightMountainBottomDark from '@/assets/images/home-right-mountain-bottom-dark.png';
import homeRightMountainBottom from '@/assets/images/home-right-mountain-bottom.webp';
import homeRightMountainBottomDark from '@/assets/images/home-right-mountain-bottom-dark.webp';
import BackgroundImageWrapper from '@/components/BackgroundImageWrapper';
import useThemeStore from '@/stores/themeStore';

Expand Down
4 changes: 2 additions & 2 deletions src/pages/Home/components/HomeBackgroundRightTop.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import homeRightMountainTop from '@/assets/images/home-right-mountain-top.png';
import homeRightMountainTopDark from '@/assets/images/home-right-mountain-top-dark.png';
import homeRightMountainTop from '@/assets/images/home-right-mountain-top.webp';
import homeRightMountainTopDark from '@/assets/images/home-right-mountain-top-dark.webp';

import BackgroundImageWrapper from '@/components/BackgroundImageWrapper';
import useThemeStore from '@/stores/themeStore';
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Home/components/HomeHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const HomeHeader = () => {
<header className="fixed top-0 z-40 flex h-16 w-full max-w-150 items-center justify-end p-5">
<div className="flex items-center gap-3">
{theme === 'light' ? (
<FlareRoundedIcon className="h-6 w-6 text-white" onClick={toggleTheme} />
) : (
<DarkModeOutlinedIcon className="h-6 w-6 text-white" onClick={toggleTheme} />
) : (
<FlareRoundedIcon className="h-6 w-6 text-white" onClick={toggleTheme} />
)}
<NotificationButton />
<Link to="/mypage">
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Home/components/RandomCheer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState } from 'react';

import randomCheerBird from '@/assets/images/field-theme-asset-bird.png';
import randomCheerBirdDark from '@/assets/images/field-theme-asset-bird-dark.png';
import randomCheerBirdDark from '@/assets/images/field-theme-asset-bird-dark.webp';

import { RANDOM_CHEER_LIST } from '../constants';
import useThemeStore from '@/stores/themeStore';
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Landing/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { useState, useEffect } from 'react';
import { Navigate, useNavigate } from 'react-router';
import { twMerge } from 'tailwind-merge';

import LandingImg from '@/assets/images/landing.png';
import LandingImgDark from '@/assets/images/landing-dark.png';
import LandingImg from '@/assets/images/landing.webp';
import LandingImgDark from '@/assets/images/landing-dark.webp';
import useAuthStore from '@/stores/authStore';
import useThemeStore from '@/stores/themeStore';

Expand Down
6 changes: 4 additions & 2 deletions src/pages/LetterBoard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,12 @@ const LetterBoardPage = () => {
})}
</section>
) : (
<p className="body-m text-gray-60 mt-10 text-center">게시글이 없습니다.</p>
<p className="body-m text-gray-60 mt-10 text-center dark:text-white">
게시글이 없습니다.
</p>
)
) : (
<p className="body-m text-gray-60 mt-10 text-center">
<p className="body-m text-gray-60 mt-10 text-center dark:text-white">
오류가 발생했습니다. 다시 한 번 시도해주세요
</p>
)}
Expand Down
39 changes: 18 additions & 21 deletions src/pages/LetterBoardDetail/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const Header = ({
onToggleLike,
onOpenReportModal,
onDeleteLetter,
isShareLetterPreview = false,
}: HeaderProps) => {
const navigate = useNavigate();
return (
Expand All @@ -34,27 +33,25 @@ const Header = ({
<button onClick={() => navigate(-1)}>
<ArrowLeftIcon className="text-primary-1 h-6 w-6" />
</button>
{!isShareLetterPreview && (
<div className="flex items-center gap-3">
<div className="flex items-center gap-1">
<button type="button" onClick={onToggleLike}>
{isLike ? (
<LikeFilledIcon className="text-primary-1 h-6 w-6" />
) : (
<LikeOutlinedIcon className="text-primary-1 h-6 w-6" />
)}
</button>
<p className="body-l-m text-primary-1">{likeCount}</p>
</div>
{isWriter ? (
<DeleteIcon className="text-primary-1 h-6 w-6" onClick={onDeleteLetter} />
) : (
<button type="button" onClick={onOpenReportModal}>
<SirenOutlinedIcon className="text-primary-1 h-6 w-6" />
</button>
)}
<div className="flex items-center gap-3">
<div className="flex items-center gap-1">
<button type="button" onClick={onToggleLike}>
{isLike ? (
<LikeFilledIcon className="text-primary-1 h-6 w-6" />
) : (
<LikeOutlinedIcon className="text-primary-1 h-6 w-6" />
)}
</button>
<p className="body-l-m text-primary-1">{likeCount}</p>
</div>
)}
{isWriter ? (
<DeleteIcon className="text-primary-1 h-6 w-6" onClick={onDeleteLetter} />
) : (
<button type="button" onClick={onOpenReportModal}>
<SirenOutlinedIcon className="text-primary-1 h-6 w-6" />
</button>
)}
</div>
</div>
<div className="h-4 w-full bg-gradient-to-b from-white to-white/0" />
</header>
Expand Down
15 changes: 7 additions & 8 deletions src/pages/LetterBoardDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Letter from './components/Letter';
import { useNavigate, useParams } from 'react-router';
import useAuthStore from '@/stores/authStore';
import useToastStore from '@/stores/toastStore';
import { useQueryClient } from '@tanstack/react-query';

const LetterBoardDetailPage = () => {
const [likeCount, setLikeCount] = useState(0);
Expand All @@ -27,13 +28,14 @@ const LetterBoardDetailPage = () => {
const { id } = useParams();
const myZipCode = useAuthStore.getState().zipCode;
const setToastActive = useToastStore((state) => state.setToastActive);

const navigate = useNavigate();
const queryClient = useQueryClient();

const postLike = async (sharePostId: string) => {
try {
const response = await postSharePostLike(sharePostId);
if (!response) throw new Error('error while fetching like count');
console.log('✅ 편지 좋아요 추가됨:', response);
} catch (error) {
console.error('❌ 편지 좋아요 추가 중 에러가 발생했습니다', error);
}
Expand All @@ -53,6 +55,7 @@ const LetterBoardDetailPage = () => {
if (id) {
const response = await deleteSharePost(id);
if (!response) throw new Error('deleteSharePost: no response');
queryClient.invalidateQueries({ queryKey: ['sharePostList'] });
navigate(-1);
setToastActive({
toastType: 'Success',
Expand All @@ -73,6 +76,9 @@ const LetterBoardDetailPage = () => {
try {
const data = await getSharePostDetail(postId);
setPostDetail(data);
if (myZipCode === data.zipCode || !data.zipCode) {
setIsWriter(true);
}
} catch (error) {
console.error('❌ 공유 게시글 상세 조회에 실패했습니다.', error);
}
Expand All @@ -85,13 +91,6 @@ const LetterBoardDetailPage = () => {
console.log('✅ 편지 좋아요 갯수:', response);
setLikeCount(response.likeCount);
setIsLike(response.liked);
console.log('myZip', myZipCode);
console.log('responseZip', response.zipCode);
console.log('responseZip', response);

if (myZipCode === response.zipCode || !response.zipCode) {
setIsWriter(true);
}
} catch (error) {
console.error('❌ 편지 좋아요 갯수를 가져오는 중 에러가 발생했습니다', error);
throw new Error('편지 좋아요 갯수 가져오기 실패');
Expand Down
6 changes: 5 additions & 1 deletion src/pages/LetterBoxDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ const LetterBoxDetailPage = () => {
}, [inView, hasNextPage, isFetchingNextPage, fetchNextPage]);

const disconnectMutation = useMutation({
mutationFn: async () => await postMailboxDisconnect(userInfo.oppositeId),
mutationFn: async () => {
console.log('userInfo', userInfo, userInfo.id);
const response = await postMailboxDisconnect(userInfo.id);
if (!response) throw new Error(`no response`);
},
onSuccess: () => {
navigate(-1);
setToastActive({
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Login/components/Background.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Link } from 'react-router';

import FieldImg from '@/assets/images/home-left-mountain.png';
import FieldImgDark from '@/assets/images/home-left-mountain-dark.png';
import FieldImg from '@/assets/images/home-left-mountain.webp';
import FieldImgDark from '@/assets/images/home-left-mountain-dark.webp';

import BlurImg from '@/assets/images/landing-blur.png';
import EnvelopeImg from '@/assets/images/postoffice-letter.png';
Expand Down
Loading