Skip to content

Commit

Permalink
feat: 펫 판매 확인창 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
sumi-0011 committed Dec 20, 2024
1 parent dbdd11c commit e4026ce
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 23 deletions.
8 changes: 7 additions & 1 deletion apps/web/messages/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@
"sell": "Sell",
"pet-list": "Pet list",
"merge": "Merge",
"prepare": "Prepare"
"prepare": "Prepare",
"confirm": "Confirm",
"close": "Close",
"processing": "Processing..."
},
"Gotcha": {
"pet-gotcha-desc": "Draw a S+ Grade pet for 1,000 points",
Expand Down Expand Up @@ -67,6 +70,9 @@
"merge": "Merge",
"edit-product": "Edit Product",
"buy-error-not-login": "Please sign in to use this feature.",
"sell-confirm": "Are you sure you want to sell?",
"sell-confirm-description": "After selling, the pet will disappear.",
"sell-confirm-checkbox": "Do not show this message again",
"Background": {
"buy-success": "Background purchased successfully",
"buy-fail": "Failed to purchase background",
Expand Down
9 changes: 8 additions & 1 deletion apps/web/messages/ko_KR.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
"pet-list": "펫 목록",
"sell": "판매",
"merge": "합치기",
"prepare": "준비중"
"prepare": "준비중",
"confirm": "확인",
"close": "닫기",
"processing": "처리중..."
},
"HomePage": {
"title": "Hello world!",
Expand Down Expand Up @@ -68,6 +71,9 @@
"prepare": "준비중",
"merge": "펫 합치기",
"edit-product": "펫 경매 수정",
"sell-confirm": "정말로 판매하시겠습니까?",
"sell-confirm-description": "판매 후 펫은 사라집니다.",
"sell-confirm-checkbox": "메시지 다시 보지 않기",
"Background": {
"buy-success": "배경 구매 완료!",
"buy-fail": "배경 구매에 실패했습니다.",
Expand Down Expand Up @@ -105,6 +111,7 @@
"invalid-size-error": "유효하지 않은 사이즈",
"farm-type-select-pet": "Farm Type에 사용할 펫을 선택해주세요.",
"line-type-select-pet": "Line Type에 사용할 펫을 선택해주세요.",

"Merge": {
"merge": "합치기",
"merge-result": "합치기 결과",
Expand Down
119 changes: 101 additions & 18 deletions apps/web/src/app/[locale]/mypage/my-pet/SelectedPetTable.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
'use client';

import { useState } from 'react';
import { useCallback, useState } from 'react';
import Image from 'next/image';
import { useTranslations } from 'next-intl';
import { css, cx } from '_panda/css';
import { Flex } from '_panda/jsx';
import { flex } from '_panda/patterns';
import { dropPet, type Persona } from '@gitanimals/api';
import { userQueries } from '@gitanimals/react-query';
import { Button, Checkbox, Label } from '@gitanimals/ui-panda';
import { Button, Checkbox, Dialog, Label } from '@gitanimals/ui-panda';
import { snakeToTitleCase } from '@gitanimals/util-common';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';

import { useDialog } from '@/components/Global/useDialog';
import { ANIMAL_TIER_TEXT_MAP, getAnimalTierInfo } from '@/utils/animals';
import { getPersonaImage } from '@/utils/image';

Expand All @@ -30,13 +29,15 @@ export function SelectedPetTable({ currentPersona, reset }: SelectedPetTableProp
const queryClient = useQueryClient();
const t = useTranslations('Shop');
const [isMergeOpen, setIsMergeOpen] = useState(false);
const { showDialog } = useDialog();
const [sellPersonaId, setSellPersonaId] = useState<string | null>(null);
const { setDoNotShowAgain, isChecked: isDoNotShowAgain } = useDoNotShowAgain();

const { mutate: dropPetMutation } = useMutation({
mutationFn: (personaId: string) => dropPet({ personaId }),
onSuccess: (data) => {
toast.success((t('pet-sold') as string).replace('[money]', data.givenPoint.toString()));
queryClient.invalidateQueries({ queryKey: userQueries.allKey() });
setSellPersonaId(null);
reset();
},
onError: () => {
Expand All @@ -46,20 +47,19 @@ export function SelectedPetTable({ currentPersona, reset }: SelectedPetTableProp

const onSellClick = async () => {
if (!currentPersona) return;
// dropPetMutation(currentPersona.id);
showDialog({
title: `${currentPersona.type} 판매하기`,
description: (
<>
<p>정말로 판매하시겠습니까?</p>
<Flex alignItems="center" gap="2">
<Checkbox id="terms" />
<Label htmlFor="terms">Accept terms and conditions</Label>
</Flex>
</>
),
onConfirm: () => dropPetMutation(currentPersona.id),
});
if (isDoNotShowAgain) {
dropPetMutation(currentPersona.id);
} else {
setSellPersonaId(currentPersona.id);
}
};

const onSellAction = async (isDoNotShowAgain: boolean) => {
if (!sellPersonaId) return;
dropPetMutation(sellPersonaId);
if (isDoNotShowAgain) {
setDoNotShowAgain(true);
}
};

return (
Expand Down Expand Up @@ -101,6 +101,11 @@ export function SelectedPetTable({ currentPersona, reset }: SelectedPetTableProp
targetPersona={currentPersona}
/>
)}
<SellConfirmDialog
isOpen={Boolean(sellPersonaId)}
onConfirm={onSellAction}
onClose={() => setSellPersonaId(null)}
/>
</div>
);
}
Expand Down Expand Up @@ -159,3 +164,81 @@ const rowStyle = css({
fontSize: '16px',
},
});

const DO_NOT_SHOW_AGAIN_KEY = '@gitanimals/do-not-show-again';

const useDoNotShowAgain = () => {
const [isChecked, setIsChecked] = useState(() => {
if (typeof window === 'undefined') return false;
return localStorage.getItem(DO_NOT_SHOW_AGAIN_KEY) === 'true';
});

const setDoNotShowAgain = useCallback((value: boolean) => {
setIsChecked(value);
if (typeof window === 'undefined') return;
localStorage.setItem(DO_NOT_SHOW_AGAIN_KEY, value.toString());
}, []);

return {
isChecked,
setDoNotShowAgain,
};
};

function SellConfirmDialog({
onConfirm,
onClose,
isOpen,
}: {
onConfirm: (isDoNotShowAgain: boolean) => Promise<void>;
onClose: () => void;
isOpen: boolean;
}) {
const [isLoading, setIsLoading] = useState(false);
const t = useTranslations();
const [isDoNotShowAgain, setIsDoNotShowAgain] = useState(false);
console.log('isDoNotShowAgain: ', isDoNotShowAgain);

const confirmDialog = async () => {
if (isLoading) return;

setIsLoading(true);
await onConfirm(isDoNotShowAgain);
setIsLoading(false);

onClose();
};

return (
<Dialog open={isOpen} onOpenChange={onClose}>
<Dialog.Content>
<Dialog.Title>{t('Shop.sell-confirm')}</Dialog.Title>
<Dialog.Description className={descriptionStyle}>
<p>{t('Shop.sell-confirm-description')}</p>
</Dialog.Description>
<Flex alignItems="center" justifyContent="space-between" width="100%">
<Flex alignItems="center" gap="2">
<Checkbox id="do-not-show-again" onClick={() => setIsDoNotShowAgain(!isDoNotShowAgain)} />
<Label htmlFor="do-not-show-again" whiteSpace="nowrap">
{t('Shop.sell-confirm-checkbox')}
</Label>
</Flex>
<Flex gap="8px" justifyContent="flex-end" width="100%">
<Button onClick={onClose} variant="secondary" size="m">
{t('Common.close')}
</Button>
<Button onClick={confirmDialog} variant="primary" size="m" disabled={isLoading}>
{isLoading ? t('Common.processing') : t('Common.confirm')}
</Button>
</Flex>
</Flex>
</Dialog.Content>
</Dialog>
);
}

const descriptionStyle = css({
textAlign: 'left',
color: 'white.white_75',
width: '100%',
});
7 changes: 4 additions & 3 deletions apps/web/src/components/Global/useDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { type ReactNode, useState } from 'react';
import { useTranslations } from 'next-intl';
import { css } from '_panda/css';
import { Flex } from '_panda/jsx';
import { Button, Dialog } from '@gitanimals/ui-panda';
Expand Down Expand Up @@ -50,7 +51,7 @@ export function useDialog() {
export function DialogComponent() {
const [dialog, setDialog] = useAtom(dialogAtom);
const [isLoading, setIsLoading] = useState(false);

const t = useTranslations('Common');
const closeDialog = () => {
setDialog((prev) => ({
...prev,
Expand Down Expand Up @@ -79,11 +80,11 @@ export function DialogComponent() {
<Flex gap="8px" justifyContent="flex-end" width="100%">
{dialog.onConfirm && (
<Button onClick={confirmDialog} variant="secondary" size="m" disabled={isLoading}>
{isLoading ? '처리중...' : '확인'}
{isLoading ? t('processing') : t('confirm')}
</Button>
)}
<Button onClick={closeDialog} variant="primary" size="m">
닫기
{t('close')}
</Button>
</Flex>
</Dialog.Content>
Expand Down

0 comments on commit e4026ce

Please sign in to comment.