diff --git a/public/assets/img/img-lcon-bm.png b/public/assets/img/img-lcon-bm.png new file mode 100644 index 0000000..b072bed Binary files /dev/null and b/public/assets/img/img-lcon-bm.png differ diff --git a/public/assets/img/img-lcon-cp.png b/public/assets/img/img-lcon-cp.png new file mode 100644 index 0000000..22d59c0 Binary files /dev/null and b/public/assets/img/img-lcon-cp.png differ diff --git a/public/assets/img/img-lcon-naver.png b/public/assets/img/img-lcon-naver.png new file mode 100644 index 0000000..15a442c Binary files /dev/null and b/public/assets/img/img-lcon-naver.png differ diff --git a/src/assets/svg/ic-again.svg b/src/assets/svg/ic-again.svg new file mode 100644 index 0000000..fcfc71d --- /dev/null +++ b/src/assets/svg/ic-again.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svg/ic-edit.svg b/src/assets/svg/ic-edit.svg new file mode 100644 index 0000000..b730ba2 --- /dev/null +++ b/src/assets/svg/ic-edit.svg @@ -0,0 +1 @@ + diff --git a/src/components/ui/Icon/Icon.tsx b/src/components/ui/Icon/Icon.tsx index 8fec8fc..6f4c51a 100644 --- a/src/components/ui/Icon/Icon.tsx +++ b/src/components/ui/Icon/Icon.tsx @@ -1,6 +1,8 @@ +import AgainIcon from "@/assets/svg/ic-again.svg?react"; import CameraIcon from "@/assets/svg/ic-camera.svg?react"; import CheckCircleIcon from "@/assets/svg/ic-check-circle.svg?react"; import CloseIcon from "@/assets/svg/ic-close.svg?react"; +import EditIcon from "@/assets/svg/ic-edit.svg?react"; import EmptyCircleIcon from "@/assets/svg/ic-empty-circle.svg?react"; import GalleryIcon from "@/assets/svg/ic-gallery.svg?react"; import LeftArrowIcon from "@/assets/svg/ic-left-arrow.svg?react"; @@ -17,7 +19,9 @@ export type IconNameType = | "plus" | "checkCircle" | "emptyCircle" - | "share"; + | "share" + | "edit" + | "again"; export interface IconProps { name: IconNameType; @@ -33,6 +37,8 @@ export const ICONS = { checkCircle: CheckCircleIcon, emptyCircle: EmptyCircleIcon, share: ShareIcon, + edit: EditIcon, + again: AgainIcon, }; // 추후 사이즈, 컬러등 추가 가능 diff --git a/src/components/ui/IconButton/IconButton.module.scss b/src/components/ui/IconButton/IconButton.module.scss index f03c184..7b6750e 100644 --- a/src/components/ui/IconButton/IconButton.module.scss +++ b/src/components/ui/IconButton/IconButton.module.scss @@ -22,6 +22,29 @@ border-radius: 0.75rem; @include buttonTertiary; } + @include buttonSecondary; + white-space: nowrap; + + &.style-primary { + background-color: var(--color-text-primary); + color: var(--color-white); + } + + &.style-secondary { + background-color: var(--color-gray400); + color: var(--color-white); + } + + &.style-tertiary { + background-color: var(--color-gray200); + color: var(--color-text-tertiary); + } + + &:disabled { + background-color: var(--color-disabled); + color: var(--color-text-tertiary); + cursor: not-allowed; + } } .IconButtonStory { diff --git a/src/components/ui/IconButton/IconButton.tsx b/src/components/ui/IconButton/IconButton.tsx index 036a372..8973fe1 100644 --- a/src/components/ui/IconButton/IconButton.tsx +++ b/src/components/ui/IconButton/IconButton.tsx @@ -17,6 +17,7 @@ const IconButton = React.forwardRef( onClick, text, iconName, + variant = "primary", ...props }, ref, @@ -35,7 +36,12 @@ const IconButton = React.forwardRef( return ( , ButtonOwnProps { size?: IconButtonSize; iconName: IconNameType; + variant?: ButtonVariant; + } + diff --git a/src/components/ui/Text/Text.module.scss b/src/components/ui/Text/Text.module.scss index e3442af..19125b3 100644 --- a/src/components/ui/Text/Text.module.scss +++ b/src/components/ui/Text/Text.module.scss @@ -42,6 +42,7 @@ titleLg, titleM, titleSm, + titleXsm, bodyLg, bodyM, bodySm, @@ -58,7 +59,10 @@ @include titleM; } @else if $variant-name == titleSm { @include titleSm; - } @else if $variant-name == bodyLg { + } @else if $variant-name == titleXsm { + @include titleXsm; + } + @else if $variant-name == bodyLg { @include bodyLg; } @else if $variant-name == bodyM { @include bodyM; diff --git a/src/components/ui/Text/Text.types.ts b/src/components/ui/Text/Text.types.ts index b831c88..dd272e7 100644 --- a/src/components/ui/Text/Text.types.ts +++ b/src/components/ui/Text/Text.types.ts @@ -2,6 +2,7 @@ type TextVariant = | "titleLg" | "titleM" | "titleSm" + | "titleXsm" | "bodyLg" | "bodyM" | "bodySm" diff --git a/src/constants/path.ts b/src/constants/path.ts index 43867c3..a023304 100644 --- a/src/constants/path.ts +++ b/src/constants/path.ts @@ -9,5 +9,5 @@ export const PATH = { LOADING: "/loading", CREATE_REVIEW_FAIL: "/create-review-fail", APP_DOWNLOAD: "/download", - + REVIEW_COPY_GUIDE: "/review-copy-guide", }; diff --git a/src/hooks/common/useRoute.ts b/src/hooks/common/useRoute.ts index f29aa34..06e0c9d 100644 --- a/src/hooks/common/useRoute.ts +++ b/src/hooks/common/useRoute.ts @@ -16,6 +16,7 @@ export const useRoute = () => { navigateToReviewResult: () => navigate(PATH.REVIEW_RESULT), navigateToLoading: () => navigate(PATH.LOADING), navigateToCreateReviewFail: () => navigate(PATH.CREATE_REVIEW_FAIL), + navigateToReviewCopyGuide: () => navigate(PATH.REVIEW_COPY_GUIDE), }; return routes; diff --git a/src/pages/ReceiptInputPage/ReceiptInputPage.tsx b/src/pages/ReceiptInputPage/ReceiptInputPage.tsx index e535f7b..7463913 100644 --- a/src/pages/ReceiptInputPage/ReceiptInputPage.tsx +++ b/src/pages/ReceiptInputPage/ReceiptInputPage.tsx @@ -114,11 +114,11 @@ const ReceiptInputPage = () => {
{Object.values(focusState).some((isFocus) => isFocus) ? ( - +
+ + +
+ + 2 + +
+ 앱을 열고 붙여넣기 해보세요 +
+ {appInfo.map(({ iconName, iconSrc }, index) => ( +
+
+ 배민 앱 아이콘 + {iconName} +
+ + {/*
+ ))} +
+
+
+ +
+
+ + + ); +}; + +export default ReviewCopyGuidePage; diff --git a/src/pages/ReviewResultPage/ReviewResultPage.module.css b/src/pages/ReviewResultPage/ReviewResultPage.module.css new file mode 100644 index 0000000..e321981 --- /dev/null +++ b/src/pages/ReviewResultPage/ReviewResultPage.module.css @@ -0,0 +1,83 @@ +.ReviewResult { + padding: 2.5rem 1.25rem; + padding-bottom: 9rem; + height: 100vh; + overflow: hidden; + position: relative; + display: flex; + flex-direction: column; + background: var(--color-bg-gradient); + justify-content: space-between; + overflow-y: scroll; + -ms-overflow-style: none; + scrollbar-width: none; +} +.ReviewResult::-webkit-scrollbar { + display: none; +} +.ReviewResult::before { + content: ""; + background: url("/src/assets/svg/img-graphic-main.svg") center no-repeat; + background-size: 100% 16.375rem; + filter: blur(4.625rem); + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 0; +} + +.Top { + z-index: 1; +} +.Top .TitleBox { + display: flex; + justify-content: center; + margin: 1.25rem 0; +} + +.Bottom { + z-index: 2; + position: fixed; + width: 100%; + height: 7rem; + left: 0; + bottom: 0; + display: grid; + grid-template-columns: 30% 1fr; + gap: 0.875rem; + background: linear-gradient(180deg, rgba(220, 220, 232, 0) 0%, rgb(220, 220, 232) 20%, rgb(220, 220, 232) 100%); +} +.Bottom > button { + margin-top: 1.25rem; +} +.Bottom > button:first-of-type { + width: calc(100% - 1.25rem); + margin-left: 1.25rem; +} +.Bottom > button:last-of-type { + width: calc(100% - 1.25rem); +} + +.Image { + display: flex; + justify-content: center; + align-items: center; + z-index: 1; +} +.Image > img { + width: 10rem; + height: 10rem; +} + +.IconBtn { + width: 6.15625rem; + margin-top: 0.625rem; + display: flex; + gap: 0.625rem; +} + +.TextBox { + width: 100%; +} \ No newline at end of file diff --git a/src/pages/ReviewResultPage/ReviewResultPage.module.scss b/src/pages/ReviewResultPage/ReviewResultPage.module.scss index a9ee189..c1826d1 100644 --- a/src/pages/ReviewResultPage/ReviewResultPage.module.scss +++ b/src/pages/ReviewResultPage/ReviewResultPage.module.scss @@ -86,5 +86,10 @@ .IconBtn { width: 6.15625rem; margin-top: 0.625rem; - margin-left: auto; + display: flex; + gap: 0.625rem; +} + +.TextBox { + width: 100%; } diff --git a/src/pages/ReviewResultPage/ReviewResultPage.tsx b/src/pages/ReviewResultPage/ReviewResultPage.tsx index 8e31063..a068f22 100644 --- a/src/pages/ReviewResultPage/ReviewResultPage.tsx +++ b/src/pages/ReviewResultPage/ReviewResultPage.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import confetti from "canvas-confetti"; @@ -11,7 +11,6 @@ import Text from "@/components/ui/Text/Text"; import { useOverlay } from "@/hooks/common/useOverlay"; import { useRoute } from "@/hooks/common/useRoute"; -import { useToast } from "@/hooks/common/useToast"; import styles from "@/pages/ReviewResultPage/ReviewResultPage.module.scss"; @@ -26,16 +25,24 @@ export default function ReviewResultPage() { const { send } = useAppBridge(); const { createReviewData } = useCreateReviewStore(); - const { generateReviewData, resetGenerateReviewData } = useGenerateReviewStore(); + const { generateReviewData, setGenerateReviewData, resetGenerateReviewData } = + useGenerateReviewStore(); + const [text, setText] = useState(generateReviewData); - const { navigateToCreateReviewFail, navigateToLoading } = useRoute(); + const { + navigateToCreateReviewFail, + navigateToLoading, + navigateToSelectStyle, + navigateToReviewCopyGuide, + } = useRoute(); const { isOpen, handleClose, handleOpen } = useOverlay(); - const { addToast } = useToast(); const { ocrText, hashTag, reviewStyle } = createReviewData; + const [isEdit, setIsEdit] = useState(false); + const handleConfetti = () => { const setting: ConfettiOptions = { particleCount: 100, @@ -48,6 +55,10 @@ export default function ReviewResultPage() { confetti(setting); }; + const handleSelectStyle = () => { + navigateToSelectStyle(); + }; + const handleRetryCreateReview = () => { gTagLogEvent("review_retry_button_click", { category: "Button", @@ -74,6 +85,14 @@ export default function ReviewResultPage() { } }, [generateReviewData]); + const handleTextChange = (e: React.ChangeEvent) => { + setText(e.target.value); + }; + + const handleCompleteEdit = () => { + setGenerateReviewData(text); + }; + return (
@@ -85,11 +104,38 @@ export default function ReviewResultPage() { 리뷰를 만들었어요!
+ {isEdit ? ( + + ) : ( + + {generateReviewData} + + )} - - {generateReviewData} -
+ { + setIsEdit(true); + }} + iconName={"edit"} + /> + +
diff --git a/src/router/AppRouter.tsx b/src/router/AppRouter.tsx index 3212122..76b7157 100644 --- a/src/router/AppRouter.tsx +++ b/src/router/AppRouter.tsx @@ -14,6 +14,7 @@ import RecognitionFailPage from "@/pages/RecognitionFailPage/RecognitionFailPage import ReviewResultPage from "@/pages/ReviewResultPage/ReviewResultPage"; import SelectStylePage from "@/pages/SelectStylePage/SelectStylePage"; import SelectTagPage from "@/pages/SelectTagPage/SelectTagPage"; +import ReviewCopyGuidePage from "@/pages/ReviewCopyGuidePage/ReviewCopyGuidePage"; const AppRouter = () => { const router = createBrowserRouter([ @@ -55,6 +56,7 @@ const AppRouter = () => { }, { path: PATH.CREATE_REVIEW_FAIL, element: }, { path: PATH.APP_DOWNLOAD, element: }, + { path: PATH.REVIEW_COPY_GUIDE, element: }, ], }, ]); diff --git a/src/styles/_mixins.scss b/src/styles/_mixins.scss index 1177b67..bbf4359 100644 --- a/src/styles/_mixins.scss +++ b/src/styles/_mixins.scss @@ -13,6 +13,11 @@ font-weight: var(--font-weight-bold); } +@mixin titleXsm { + font-size: var(--font-size-18); + font-weight: var(--font-weight-bold); +} + @mixin bodyLg { font-size: var(--font-size-16); font-weight: var(--font-weight-medium); diff --git a/src/styles/_variables.scss b/src/styles/_variables.scss index d62c4e6..7ca22e6 100644 --- a/src/styles/_variables.scss +++ b/src/styles/_variables.scss @@ -7,6 +7,7 @@ --font-size-28: 1.75rem; --font-size-24: 1.5rem; --font-size-22: 1.375rem; + --font-size-18: 1.125rem; --font-size-16: 1rem; --font-size-15: 0.9375rem; --font-size-14: 0.875rem;