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
18 changes: 17 additions & 1 deletion src/apis/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
import axios from 'axios';

export const client = axios.create({
const client = axios.create({
baseURL: import.meta.env.VITE_API_URL,
});

// client.interceptors.request.use(
// (config) => {
// const token = localStorage.getItem('authToken');
// if (token) {
// config.headers['Authorization'] = `Bearer ${token}`;
// }
// return config;
// },
// (error) => {
// //TODO: 에러처리
// return Promise.reject(error);
// },
// );

export default client;
2 changes: 1 addition & 1 deletion src/apis/letterDetail.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { client } from './client';
import client from './client';

const getLetter = async (
letterId: string,
Expand Down
31 changes: 31 additions & 0 deletions src/apis/mailBox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import client from './client';

export const getMailbox = async () => {
try {
const response = await client.get('/api/mailbox');
if (!response) throw new Error('error while fetching mailbox data');
return response.data;
} catch (error) {
console.error(error);
}
};

export const getMailboxDetail = async (id: number) => {
try {
const response = await client.get(`/api/mailbox/${id}`);
if (!response) throw new Error('error while fetching mailbox detail data');
return response.data;
} catch (error) {
console.error(error);
}
};

export const postMailboxDisconnect = async (id: number) => {
try {
const response = await client.post(`/api/mailbox/${id}/disconnect`);
if (!response) throw new Error('error while disconnecting mailbox');
return response;
} catch (error) {
console.error(error);
}
};
21 changes: 21 additions & 0 deletions src/apis/share.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import client from './client';

export const postShareProposals = async (
letterIds: number[],
requesterId: number,
recipientId: number,
message: string,
) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

취향차이일거 같지만 저는 post보낼때 데이터를 따로 변수에 담아서 인자 1개로 전송하는 편입니당!

  • api함수

const postLetter = async (data: LetterRequest, callBack?: () => void) => {
try {
const res = await client.post('/api/letters', data);
if (callBack) callBack();
console.log(res);
} catch (error) {
console.error(error);
}
};

  • data

const LETTER_REQUEST: LetterRequest = {
receiverId: null,
parentLetterId: null,
title: letterTitle,
content: letterText,
category: category,
paperType: paperType,
fontType: fontType,
};

try {
const response = await client.post('/api/share-proposals', {
letterIds: letterIds,
requesterId: requesterId,
recipientId: recipientId,
message: message,
});
if (!response) throw new Error('error while fetching mailbox data');
return response;
} catch (error) {
console.error(error);
}
};
2 changes: 1 addition & 1 deletion src/apis/write.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { client } from './client';
import client from './client';

const postLetter = async (
data: LetterRequest,
Expand Down
Binary file added src/assets/images/window-disabled.png
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/pages/Admin/Report.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';

import { client } from '@/apis/client';
import client from '@/apis/client';
import { AlarmIcon } from '@/assets/icons';

import DetailFrame from './components/DetailFrame';
Expand Down
3 changes: 1 addition & 2 deletions src/pages/LetterBoardDetail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { useState } from 'react';
import { useLocation } from 'react-router';

import { twMerge } from 'tailwind-merge';

import BlurImg from '@/assets/images/landing-blur.png';
import ReportModal from '@/components/ReportModal';

import Header from './components/Header';
import Letter from './components/Letter';

import BlurImg from '@/assets/images/landing-blur.png';
const DUMMY_LETTER = {
receiver: '12E21',
content:
Expand Down
78 changes: 45 additions & 33 deletions src/pages/LetterBox/components/LetterBoxItem.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,66 @@
import { Link } from 'react-router';
import { useNavigate } from 'react-router';
import { twMerge } from 'tailwind-merge';

interface LetterBoxItemProps {
boxId: number;
zipCode: string;
letterCount: number;
isChecked?: boolean;
isClosed?: boolean;
}

const LetterBoxItem = ({
boxId,
zipCode,
letterCount,
isChecked = false,
isClosed = false,
}: LetterBoxItemProps) => {
const navigate = useNavigate();
const handleClickItem = (id: number) => {
navigate(`${id}`, {
state: {
id,
zipCode,
isClosed,
},
});
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 navigate에 인자가 각각 무슨 역할을 하는건가용? 저는 navigate('/') 같은 라우팅만 해봐서요!!

return (
<Link to="id">
<article className="flex h-fit w-fit flex-col items-center">
<div className="text-gray-70 flex h-25 w-20 flex-col gap-1.5 bg-linear-to-b from-[#D5B695] to-[#B3895D] p-1.5">
<p
<article
className="flex h-fit w-fit flex-col items-center"
onClick={() => handleClickItem(boxId)}
>
<div className="text-gray-70 flex h-25 w-20 flex-col gap-1.5 bg-linear-to-b from-[#D5B695] to-[#B3895D] p-1.5">
<p
className={twMerge(
'body-m from-white px-1',
isClosed
? 'bg-[repeating-linear-gradient(#D9D9D9,#D9D9D9_17px,#C2C2C2_17px,#C2C2C2_23px)]'
: 'bg-linear-to-b',
isChecked ? 'to-[#FFF5ED]' : 'to-[#FFF4F2]',
)}
>
{zipCode}
</p>
{isClosed ? (
<div className="flex grow flex-col bg-[repeating-linear-gradient(#D9D9D9,#D9D9D9_15px,#C2C2C2_15px,#C2C2C2_20px)]" />
) : (
<div
className={twMerge(
'body-m from-white px-1',
isClosed
? 'bg-[repeating-linear-gradient(#D9D9D9,#D9D9D9_17px,#C2C2C2_17px,#C2C2C2_23px)]'
: 'bg-linear-to-b',
isChecked ? 'to-[#FFF5ED]' : 'to-[#FFF4F2]',
'flex grow flex-col bg-linear-to-b',
isChecked ? 'from-[#FFF7E3] to-[#FFE197]' : 'from-[#FFF4F2] to-[#FFE6E3]',
)}
>
{zipCode}
</p>
{isClosed ? (
<div className="flex grow flex-col bg-[repeating-linear-gradient(#D9D9D9,#D9D9D9_15px,#C2C2C2_15px,#C2C2C2_20px)]" />
) : (
<div
className={twMerge(
'flex grow flex-col bg-linear-to-b',
isChecked ? 'from-[#FFF7E3] to-[#FFE197]' : 'from-[#FFF4F2] to-[#FFE6E3]',
)}
>
<p className="body-r mt-auto mr-[1px] text-right">{letterCount}</p>
</div>
)}
</div>
<div className="flex flex-col items-center">
<div className="h-[7px] w-23 bg-[#D7A877]" />
<div className="h-[3px] w-20 bg-[#A88156]" />
<div className="h-1 w-18 bg-[#917B63]" />
</div>
</article>
</Link>
<p className="body-r mt-auto mr-[1px] text-right">{letterCount}</p>
</div>
)}
</div>
<div className="flex flex-col items-center">
<div className="h-[7px] w-23 bg-[#D7A877]" />
<div className="h-[3px] w-20 bg-[#A88156]" />
<div className="h-1 w-18 bg-[#917B63]" />
</div>
</article>
);
};

Expand Down
80 changes: 61 additions & 19 deletions src/pages/LetterBox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,81 @@
import { useEffect, useState } from 'react';

import { getMailbox } from '@/apis/mailBox';
import DoorImg from '@/assets/images/door.png';
import ClosedWindowImg from '@/assets/images/window-disabled.png';
import PageTitle from '@/components/PageTitle';
import { chunkBox } from '@/utils/chunkBox';

import LetterBoxItem from './components/LetterBoxItem';

const DUMMY_COUNT = 200;

interface LetterBoxData {
letterMatchingId: number;
oppositeZipCode: string;
active: boolean;
oppositeRead: boolean;
// totalLetters: number;
}
const LetterBoxPage = () => {
const [letterBox, setLetterBox] = useState<LetterBoxData[]>([]);

const fetchMailLists = async () => {
try {
const response = await getMailbox();
if (!response) throw new Error();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오오오 try문 코드 안에서 에러코드를 안 만들고 있었는데 이렇게 만들어야 에러 파악이 더 체계적으로 이루어지는군용 저도 예외처리 코드 수정해보겠습니다!!👍👍👍👍

const data: LetterBoxData[] = response.data;
// 정렬?
setLetterBox(data);
} catch (error) {
console.error(error);
}
};
useEffect(() => {
fetchMailLists();
}, []);

return (
<main className="flex grow flex-col items-center px-5 pt-20">
<PageTitle>내 편지함</PageTitle>
<div className="w-full max-w-94">
<p className="body-sb mt-16 mb-[7px] place-self-start text-gray-50">
나와 연락한 사람들 {DUMMY_COUNT}
나와 연락한 사람들 {letterBox?.length}
</p>
<section className="letter-box-bg flex grow flex-col items-center px-4 pt-5">
<div className="flex w-full flex-col gap-5">
{chunkBox(
Array.from({ length: 12 }).map((_, index) => (
<LetterBoxItem
key={index}
zipCode="12E12"
letterCount={90}
isChecked={index % 2 === 0}
/>
)),
).map((row, index) => (
<div key={index} className="flex justify-between">
{row}
</div>
))}
{letterBox.length > 0 ? (
chunkBox(
letterBox.map((data: LetterBoxData, index) => (
<LetterBoxItem
boxId={data.letterMatchingId}
key={index}
zipCode={data.oppositeZipCode}
letterCount={90}
isChecked={data.oppositeRead}
isClosed={data.active}
/>
)),
).map((row, index) =>
row.length === 3 ? (
<div key={index} className="flex justify-between">
{row}
</div>
) : (
<div key={index} className="flex justify-between">
{row}
<img src={ClosedWindowImg} alt="닫힌 문 이미지" className="h-28 w-23" />
{row.length === 1 && (
<img src={ClosedWindowImg} alt="닫힌 문 이미지" className="h-28 w-23" />
)}
</div>
),
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

letterBox를 3개씩 분류해 배열에 담고 그걸 반복문 돌려서 3개가 안 담긴 배열엔 닫힌 문을 채워서 UI를 나타내신건가용(그냥 질문입니당)

) : (
<p className="body-m text-gray-60 text-center">아직 주고 받은 편지가 없어요</p>
)}
<div className="flex justify-between">
<LetterBoxItem zipCode="12E12" letterCount={90} isClosed />
<img src={ClosedWindowImg} alt="닫힌 문 이미지" className="h-28 w-23" />
<img src={DoorImg} alt="출입문 이미지" />
<LetterBoxItem zipCode="12E12" letterCount={90} isClosed />
<img src={ClosedWindowImg} alt="닫힌 문 이미지" className="h-28 w-23" />
</div>
</div>
</section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const InformationTooltip = () => {
</button>
<article
className={twMerge(
'bg-gray-5 absolute top-6 -right-1 z-20 w-75 rounded-md p-4 drop-shadow-sm transition-opacity duration-200',
'absolute top-6 -right-1 z-20 w-75 rounded-md bg-white p-4 drop-shadow-sm transition-opacity duration-200',
isShow ? 'opacity-100' : 'pointer-events-none opacity-0',
)}
>
Expand Down
29 changes: 22 additions & 7 deletions src/pages/LetterBoxDetail/components/LetterPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link } from 'react-router';
import { useNavigate } from 'react-router';

import ListItemWrapper from '@/components/ListItemWrapper';

Expand All @@ -10,6 +10,8 @@ interface LetterPreviewProps {
checked: boolean;
isShareMode?: boolean;
onToggle: () => void;
isClosed: boolean;
zipCode: string;
}
const LetterPreview = ({
id,
Expand All @@ -19,7 +21,22 @@ const LetterPreview = ({
checked,
isShareMode = false,
onToggle,
isClosed,
zipCode,
}: LetterPreviewProps) => {
// 차단된 편지인경우 편지 보내기 disable
const navigate = useNavigate();

const handleItemClick = (id: number) => {
navigate(`/letter/${id}`, {
state: {
id,
isClosed,
zipCode,
},
});
};

if (isShareMode)
return (
<ListItemWrapper isSender={isSend}>
Expand All @@ -41,12 +58,10 @@ const LetterPreview = ({
);

return (
<Link to={`/letter/${id}`}>
<ListItemWrapper isSender={isSend}>
<p className="body-r text-gray-80 mb-3">{date}</p>
<p className="body-m text-gray-80 line-clamp-1 break-all">{title}</p>
</ListItemWrapper>
</Link>
<ListItemWrapper isSender={isSend} onClick={() => handleItemClick(id)}>
<p className="body-r text-gray-80 mb-3">{date}</p>
<p className="body-m text-gray-80 line-clamp-1 break-all">{title}</p>
</ListItemWrapper>
);
};

Expand Down
Loading