diff --git a/public/assets/icons/ic_x.svg b/public/assets/icons/ic_x.svg new file mode 100644 index 00000000..19337c66 --- /dev/null +++ b/public/assets/icons/ic_x.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/api/image/image.tsx b/src/api/image/image.tsx index c19f84c1..52482927 100644 --- a/src/api/image/image.tsx +++ b/src/api/image/image.tsx @@ -1,12 +1,12 @@ -import { authClient } from "../client"; +import client from '../client'; export const postImage = async (imageFile: File) => { const formData = new FormData(); - formData.append("image", imageFile); + formData.append('image', imageFile); - return await authClient.post("/api/v1/images", formData, { + return await client.post('/api/v1/images', formData, { headers: { - "Content-Type": "multipart/form-data", - }, + 'Content-Type': 'multipart/form-data' + } }); }; diff --git a/src/api/letter/share.tsx b/src/api/letter/share.tsx index 351635fd..58f653cc 100644 --- a/src/api/letter/share.tsx +++ b/src/api/letter/share.tsx @@ -1,20 +1,20 @@ -import { authClient } from "../client"; +import client, { authClient } from '../client'; export const getLetterShareStatus = async ( letterCode: string ): Promise => { - const response = await authClient.get( + const response = await client.get( `/api/v1/letters/logs/share/status?letterCode=${letterCode}` ); return response.data; }; export type shareStatusType = - | "MEMO_CHAT" - | "DIRECT_CHAT" - | "MULTI_CHAT" - | "OPEN_DIRECT_CHAT" - | "OPEN_MULTI_CHAT"; + | 'MEMO_CHAT' + | 'DIRECT_CHAT' + | 'MULTI_CHAT' + | 'OPEN_DIRECT_CHAT' + | 'OPEN_MULTI_CHAT'; export type ShareStatusData = { isShared: boolean; diff --git a/src/api/login/user.tsx b/src/api/login/user.tsx index b8788c4e..685fed77 100644 --- a/src/api/login/user.tsx +++ b/src/api/login/user.tsx @@ -15,14 +15,16 @@ export const signup = async ({ servicePermission, privatePermission, marketingPermission, - realName + realName, + anonymousSendLetterCode }: RegisterDataType) => { return await client.post(`/api/v1/users`, { registerToken: registerToken, servicePermission: servicePermission, privatePermission: privatePermission, marketingPermission: marketingPermission, - realName: realName + realName: realName, + anonymousSendLetterCode: anonymousSendLetterCode }); }; diff --git a/src/api/send/send.tsx b/src/api/send/send.tsx index da3b3a0b..8e051c9d 100644 --- a/src/api/send/send.tsx +++ b/src/api/send/send.tsx @@ -1,7 +1,7 @@ -import { authClient } from '@/api/client'; +import client, { authClient } from '@/api/client'; // 편지 쓰기 -export const postSendLtter = async ({ +export const postSendLetter = async ({ receiverName, content, images, @@ -22,3 +22,23 @@ export const postSendLtter = async ({ draftId }); }; + +// 비회원 편지 쓰기 +export const postAnonymousSendLetter = async ({ + receiverName, + content, + images, + templateType +}: { + receiverName: string; + content: string; + images: string[]; + templateType: number; +}) => { + return await client.post(`/api/v1/letters/anonymous/send`, { + receiverName, + content, + images, + templateType + }); +}; diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 760717e3..72c777f2 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -3,16 +3,37 @@ import Loader, { LoaderContainer } from '@/components/common/Loader'; import OauthButton from '@/components/signup/OauthButton'; import { OAUTH } from '@/constants/oauth'; +import { sendLetterState } from '@/recoil/letterStore'; import { theme } from '@/styles/theme'; import { OAuthType } from '@/types/login'; -import { Suspense } from 'react'; +import { clearAnonymousSendLetterCode } from '@/utils/storage'; +import { useRouter } from 'next/navigation'; +import { Suspense, useEffect } from 'react'; +import { useRecoilState } from 'recoil'; import styled from 'styled-components'; -const notReady = () => { - alert('준비 중입니다.'); -}; - export default function Login() { + const router = useRouter(); + const [, setSendState] = useRecoilState(sendLetterState); + + /* 로그인 페이지에서 편지 쓰기 store 초기화 */ + useEffect(() => { + clearAnonymousSendLetterCode(); + setSendState({ + draftId: null, + receiverName: '', + content: '', + images: [] as string[], + previewImages: [] as string[], + templateType: 0, + letterId: null + }); + }, []); + + const handleGuestLetterStart = () => { + router.push('/send/receiver?guest=true'); + }; + return ( @@ -38,8 +59,8 @@ export default function Login() { ))} - - 로그인 없이 편지 작성해보기 + + 로그인 없이 편지 보내기 diff --git a/src/app/page.tsx b/src/app/page.tsx index 2864ffb4..6e09152e 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,19 +1,10 @@ -"use client"; +'use client'; -import { getAllSpaceName, getNewTokens } from "@/api/login/user"; -import Button from "@/components/common/Button"; -import KakaoShareButton from "@/components/common/KakaoShareButton"; -import Loader from "@/components/common/Loader"; -import { - clearInitUserToast, - clearTokens, - getAccessToken, - getCookie, - setCookie, -} from "@/utils/storage"; -import { useRouter } from "next/navigation"; -import { useEffect, useState } from "react"; -import styled from "styled-components"; +import Loader, { LoaderContainer } from '@/components/common/Loader'; +import { getAccessToken } from '@/utils/storage'; +import { useRouter } from 'next/navigation'; +import { useEffect } from 'react'; +import styled from 'styled-components'; export default function Home() { const router = useRouter(); @@ -21,22 +12,17 @@ export default function Home() { useEffect(() => { if (!accessToken) { - router.push("/login"); + router.push('/login'); } else { - router.push("/planet"); + router.push('/planet'); } }, []); return ( - {/* - - - */} + + + ); } @@ -49,19 +35,3 @@ const Container = styled.div` padding: 25px; background: ${(props) => props.theme.colors.bg}; `; - -const LoaderContainer = styled.div` - width: 100%; - height: 100%; - min-height: 600px; - display: flex; - align-items: center; - justify-content: center; -`; - -const ButtonContainer = styled.div` - width: 100%; - display: flex; - flex-direction: column; - gap: 10px; -`; diff --git a/src/app/send/(process)/content/page.tsx b/src/app/send/(process)/content/page.tsx index 486129c5..1672bf32 100644 --- a/src/app/send/(process)/content/page.tsx +++ b/src/app/send/(process)/content/page.tsx @@ -1,11 +1,11 @@ 'use client'; -import React, { useEffect, useState } from 'react'; +import React, { Suspense, useEffect, useState } from 'react'; import styled, { css } from 'styled-components'; import { theme } from '@/styles/theme'; import Input from '@/components/common/Input'; import Button from '@/components/common/Button'; -import { useRouter } from 'next/navigation'; +import { useRouter, useSearchParams } from 'next/navigation'; import Image from 'next/image'; import { @@ -22,11 +22,12 @@ import { useToast } from '@/hooks/useToast'; import { postImage } from '@/api/image/image'; import ConfirmModal from '@/components/common/ConfirmModal'; import { draftModalState } from '@/recoil/draftStore'; -import imageCompression from 'browser-image-compression'; import DraftButton from '@/components/draft/DraftButton'; +import Loader, { LoaderContainer } from '@/components/common/Loader'; const SendContentPage = () => { const router = useRouter(); + const searchParams = useSearchParams(); const { showToast } = useToast(); const [draftId, setDraftId] = useState(null); const [receiver, setReceiver] = useState(''); @@ -39,6 +40,8 @@ const SendContentPage = () => { const [isImageUploadLoading, setImageUploadLoading] = useState(false); // 서버 이미지 업로드 상태 + const isGuest = searchParams.get('guest') === 'true'; + const [draftModal, setDraftModal] = useRecoilState(draftModalState); const [letterState, setLetterState] = useRecoilState(sendLetterState); const [tempCount, setTempCount] = useState(3); @@ -81,7 +84,7 @@ const SendContentPage = () => { } }; - fetchGetDraftCount(); + if (!isGuest) fetchGetDraftCount(); if (draftKey) { fetchGetDraft(); @@ -263,7 +266,8 @@ const SendContentPage = () => { images: images, previewImages: previewImages })); - router.push('/send/template'); + + router.push(`/send/template${isGuest ? '?guest=true' : ''}`); }; /* 임시 저장 삭제 핸들러 */ @@ -317,13 +321,15 @@ const SendContentPage = () => { return ( <> - + {!isGuest && ( + + )}