Skip to content

Commit 0f1e6d3

Browse files
authored
Merge pull request #171 from ASAP-Lettering/feat/#170
[Feat] 비회원 편지 전송
2 parents 769d9c8 + f10adf1 commit 0f1e6d3

File tree

21 files changed

+486
-173
lines changed

21 files changed

+486
-173
lines changed

public/assets/icons/ic_x.svg

Lines changed: 6 additions & 0 deletions
Loading

src/api/image/image.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { authClient } from "../client";
1+
import client from '../client';
22

33
export const postImage = async (imageFile: File) => {
44
const formData = new FormData();
5-
formData.append("image", imageFile);
5+
formData.append('image', imageFile);
66

7-
return await authClient.post("/api/v1/images", formData, {
7+
return await client.post('/api/v1/images', formData, {
88
headers: {
9-
"Content-Type": "multipart/form-data",
10-
},
9+
'Content-Type': 'multipart/form-data'
10+
}
1111
});
1212
};

src/api/letter/share.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import { authClient } from "../client";
1+
import client, { authClient } from '../client';
22

33
export const getLetterShareStatus = async (
44
letterCode: string
55
): Promise<ShareStatusData> => {
6-
const response = await authClient.get(
6+
const response = await client.get(
77
`/api/v1/letters/logs/share/status?letterCode=${letterCode}`
88
);
99
return response.data;
1010
};
1111

1212
export type shareStatusType =
13-
| "MEMO_CHAT"
14-
| "DIRECT_CHAT"
15-
| "MULTI_CHAT"
16-
| "OPEN_DIRECT_CHAT"
17-
| "OPEN_MULTI_CHAT";
13+
| 'MEMO_CHAT'
14+
| 'DIRECT_CHAT'
15+
| 'MULTI_CHAT'
16+
| 'OPEN_DIRECT_CHAT'
17+
| 'OPEN_MULTI_CHAT';
1818

1919
export type ShareStatusData = {
2020
isShared: boolean;

src/api/login/user.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,16 @@ export const signup = async ({
1515
servicePermission,
1616
privatePermission,
1717
marketingPermission,
18-
realName
18+
realName,
19+
anonymousSendLetterCode
1920
}: RegisterDataType) => {
2021
return await client.post(`/api/v1/users`, {
2122
registerToken: registerToken,
2223
servicePermission: servicePermission,
2324
privatePermission: privatePermission,
2425
marketingPermission: marketingPermission,
25-
realName: realName
26+
realName: realName,
27+
anonymousSendLetterCode: anonymousSendLetterCode
2628
});
2729
};
2830

src/api/send/send.tsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { authClient } from '@/api/client';
1+
import client, { authClient } from '@/api/client';
22

33
// 편지 쓰기
4-
export const postSendLtter = async ({
4+
export const postSendLetter = async ({
55
receiverName,
66
content,
77
images,
@@ -22,3 +22,23 @@ export const postSendLtter = async ({
2222
draftId
2323
});
2424
};
25+
26+
// 비회원 편지 쓰기
27+
export const postAnonymousSendLetter = async ({
28+
receiverName,
29+
content,
30+
images,
31+
templateType
32+
}: {
33+
receiverName: string;
34+
content: string;
35+
images: string[];
36+
templateType: number;
37+
}) => {
38+
return await client.post(`/api/v1/letters/anonymous/send`, {
39+
receiverName,
40+
content,
41+
images,
42+
templateType
43+
});
44+
};

src/app/login/page.tsx

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,37 @@
33
import Loader, { LoaderContainer } from '@/components/common/Loader';
44
import OauthButton from '@/components/signup/OauthButton';
55
import { OAUTH } from '@/constants/oauth';
6+
import { sendLetterState } from '@/recoil/letterStore';
67
import { theme } from '@/styles/theme';
78
import { OAuthType } from '@/types/login';
8-
import { Suspense } from 'react';
9+
import { clearAnonymousSendLetterCode } from '@/utils/storage';
10+
import { useRouter } from 'next/navigation';
11+
import { Suspense, useEffect } from 'react';
12+
import { useRecoilState } from 'recoil';
913
import styled from 'styled-components';
1014

11-
const notReady = () => {
12-
alert('준비 중입니다.');
13-
};
14-
1515
export default function Login() {
16+
const router = useRouter();
17+
const [, setSendState] = useRecoilState(sendLetterState);
18+
19+
/* 로그인 페이지에서 편지 쓰기 store 초기화 */
20+
useEffect(() => {
21+
clearAnonymousSendLetterCode();
22+
setSendState({
23+
draftId: null,
24+
receiverName: '',
25+
content: '',
26+
images: [] as string[],
27+
previewImages: [] as string[],
28+
templateType: 0,
29+
letterId: null
30+
});
31+
}, []);
32+
33+
const handleGuestLetterStart = () => {
34+
router.push('/send/receiver?guest=true');
35+
};
36+
1637
return (
1738
<Container>
1839
<ImageWrapper>
@@ -38,8 +59,8 @@ export default function Login() {
3859
))}
3960
</Suspense>
4061
</OauthWrapper>
41-
<LetterBtnText onClick={notReady}>
42-
로그인 없이 편지 작성해보기
62+
<LetterBtnText onClick={handleGuestLetterStart}>
63+
로그인 없이 편지 보내기
4364
</LetterBtnText>
4465
</ImageWrapper>
4566
</Container>

src/app/page.tsx

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,28 @@
1-
"use client";
1+
'use client';
22

3-
import { getAllSpaceName, getNewTokens } from "@/api/login/user";
4-
import Button from "@/components/common/Button";
5-
import KakaoShareButton from "@/components/common/KakaoShareButton";
6-
import Loader from "@/components/common/Loader";
7-
import {
8-
clearInitUserToast,
9-
clearTokens,
10-
getAccessToken,
11-
getCookie,
12-
setCookie,
13-
} from "@/utils/storage";
14-
import { useRouter } from "next/navigation";
15-
import { useEffect, useState } from "react";
16-
import styled from "styled-components";
3+
import Loader, { LoaderContainer } from '@/components/common/Loader';
4+
import { getAccessToken } from '@/utils/storage';
5+
import { useRouter } from 'next/navigation';
6+
import { useEffect } from 'react';
7+
import styled from 'styled-components';
178

189
export default function Home() {
1910
const router = useRouter();
2011
const accessToken = getAccessToken();
2112

2213
useEffect(() => {
2314
if (!accessToken) {
24-
router.push("/login");
15+
router.push('/login');
2516
} else {
26-
router.push("/planet");
17+
router.push('/planet');
2718
}
2819
}, []);
2920

3021
return (
3122
<Container>
32-
{/* <ButtonContainer>
33-
<Button
34-
buttonType="primary"
35-
text="로그아웃하기"
36-
onClick={handleLogout}
37-
></Button>
38-
<KakaoShareButton letterId="aa" />
39-
</ButtonContainer> */}
23+
<LoaderContainer>
24+
<Loader />
25+
</LoaderContainer>
4026
</Container>
4127
);
4228
}
@@ -49,19 +35,3 @@ const Container = styled.div`
4935
padding: 25px;
5036
background: ${(props) => props.theme.colors.bg};
5137
`;
52-
53-
const LoaderContainer = styled.div`
54-
width: 100%;
55-
height: 100%;
56-
min-height: 600px;
57-
display: flex;
58-
align-items: center;
59-
justify-content: center;
60-
`;
61-
62-
const ButtonContainer = styled.div`
63-
width: 100%;
64-
display: flex;
65-
flex-direction: column;
66-
gap: 10px;
67-
`;

src/app/send/(process)/content/page.tsx

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
'use client';
22

3-
import React, { useEffect, useState } from 'react';
3+
import React, { Suspense, useEffect, useState } from 'react';
44
import styled, { css } from 'styled-components';
55
import { theme } from '@/styles/theme';
66
import Input from '@/components/common/Input';
77
import Button from '@/components/common/Button';
8-
import { useRouter } from 'next/navigation';
8+
import { useRouter, useSearchParams } from 'next/navigation';
99
import Image from 'next/image';
1010

1111
import {
@@ -22,11 +22,12 @@ import { useToast } from '@/hooks/useToast';
2222
import { postImage } from '@/api/image/image';
2323
import ConfirmModal from '@/components/common/ConfirmModal';
2424
import { draftModalState } from '@/recoil/draftStore';
25-
import imageCompression from 'browser-image-compression';
2625
import DraftButton from '@/components/draft/DraftButton';
26+
import Loader, { LoaderContainer } from '@/components/common/Loader';
2727

2828
const SendContentPage = () => {
2929
const router = useRouter();
30+
const searchParams = useSearchParams();
3031
const { showToast } = useToast();
3132
const [draftId, setDraftId] = useState<string | null>(null);
3233
const [receiver, setReceiver] = useState<string>('');
@@ -39,6 +40,8 @@ const SendContentPage = () => {
3940
const [isImageUploadLoading, setImageUploadLoading] =
4041
useState<boolean>(false); // 서버 이미지 업로드 상태
4142

43+
const isGuest = searchParams.get('guest') === 'true';
44+
4245
const [draftModal, setDraftModal] = useRecoilState(draftModalState);
4346
const [letterState, setLetterState] = useRecoilState(sendLetterState);
4447
const [tempCount, setTempCount] = useState<number>(3);
@@ -81,7 +84,7 @@ const SendContentPage = () => {
8184
}
8285
};
8386

84-
fetchGetDraftCount();
87+
if (!isGuest) fetchGetDraftCount();
8588

8689
if (draftKey) {
8790
fetchGetDraft();
@@ -263,7 +266,8 @@ const SendContentPage = () => {
263266
images: images,
264267
previewImages: previewImages
265268
}));
266-
router.push('/send/template');
269+
270+
router.push(`/send/template${isGuest ? '?guest=true' : ''}`);
267271
};
268272

269273
/* 임시 저장 삭제 핸들러 */
@@ -317,13 +321,15 @@ const SendContentPage = () => {
317321

318322
return (
319323
<>
320-
<DraftButton
321-
handleSaveLetter={handleSaveLetter}
322-
handleDraftBottom={handleDraftBottom}
323-
isDraftDisabled={isDraftDisabled}
324-
isImageUploadLoading={isImageUploadLoading}
325-
tempCount={tempCount}
326-
/>
324+
{!isGuest && (
325+
<DraftButton
326+
handleSaveLetter={handleSaveLetter}
327+
handleDraftBottom={handleDraftBottom}
328+
isDraftDisabled={isDraftDisabled}
329+
isImageUploadLoading={isImageUploadLoading}
330+
tempCount={tempCount}
331+
/>
332+
)}
327333
<Container>
328334
<div>
329335
<Label>
@@ -420,7 +426,19 @@ const SendContentPage = () => {
420426
);
421427
};
422428

423-
export default SendContentPage;
429+
export default function SendContentPaging() {
430+
return (
431+
<Suspense
432+
fallback={
433+
<LoaderContainer>
434+
<Loader />
435+
</LoaderContainer>
436+
}
437+
>
438+
<SendContentPage />
439+
</Suspense>
440+
);
441+
}
424442

425443
const Container = styled.div`
426444
width: 100%;

0 commit comments

Comments
 (0)