Skip to content

Commit

Permalink
Merge pull request #53 from DearMyPeace/52-diary-setting-수정사항
Browse files Browse the repository at this point in the history
fix: diary, setting 수정사항
  • Loading branch information
chanhihi authored Jul 3, 2024
2 parents 5e39255 + a80bdd5 commit 48464e9
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 75 deletions.
5 changes: 2 additions & 3 deletions src/api/diary/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const fetchDiaryList = async (targetDate: string): Promise<IDiaryListResp

export const useDiaryList = (targetDate: string, dateStatus: DateStatus | null) => {
return useQuery({
queryKey: ['diaryList', targetDate],
queryKey: ['diary', 'list', targetDate],
queryFn: () => fetchDiaryList(targetDate),
enabled: !!dateStatus,
staleTime: Infinity,
Expand All @@ -35,14 +35,13 @@ export const useDiaryList = (targetDate: string, dateStatus: DateStatus | null)
};

export const fetchDiaryCounts = async ({ year, month }: IDate): Promise<IDiaryCount[]> => {
console.log('fetchDiaryCounts', year, month);
const response = await instance.get(`/diary/${year}/${month}`);
return response.data;
};

export const useDiaryCounts = ({ year, month }: IDate): UseQueryResult<IDiaryCount[]> => {
return useQuery({
queryKey: ['diaryCounts', year, month],
queryKey: ['diary', 'counts', year, month],
queryFn: () => fetchDiaryCounts({ year, month }),
enabled: !!year && !!month,
staleTime: Infinity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,27 @@ import MyText from '@components/common/MyText';
import TextButton from '@components/common/TextButton';
import { StyleSheet, View } from 'react-native';
import MyModal from '@components/common/MyModal';
import useLogout from '@hooks/login/logoutHook';

interface IDeleteAccountModalProps {
visible: boolean;
setIsVisible: React.Dispatch<React.SetStateAction<boolean>>;
}

const DeleteAccountModal = ({ visible, setIsVisible }: IDeleteAccountModalProps) => {
const { deleteAccountMutation } = useLogout();

const onDeleteAccount = () => {
deleteAccountMutation.mutate();
setIsVisible(false);
};
import { IBasicModalProps } from '@type/Modal';

const BasicConfirmModal = ({
visible,
setIsVisible,
onConfirm,
content,
confirmText = '확인',
}: IBasicModalProps) => {
const onCancel = () => {
setIsVisible(false);
};

return (
<MyModal visible={visible} setIsVisible={setIsVisible} transparent={true} animationType="fade">
<View style={styles.modalContent}>
<MyText>정말로 탈퇴하시겠습니까?</MyText>
<MyText>작성한 모든 심심기록이 지워집니다.</MyText>
<MyText style={{ textAlign: 'center' }}>{content}</MyText>
</View>
<View style={styles.modalButtons}>
<TextButton onPress={onCancel}>취소</TextButton>
<TextButton onPress={onDeleteAccount}>확인</TextButton>
<TextButton onPress={onConfirm}>{confirmText}</TextButton>
</View>
</MyModal>
);
Expand All @@ -52,4 +45,4 @@ const styles = StyleSheet.create({
},
});

export default DeleteAccountModal;
export default BasicConfirmModal;
10 changes: 2 additions & 8 deletions src/components/common/MyModal.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import React from 'react';
import { Modal, ModalProps, Pressable, StyleProp, StyleSheet, ViewStyle } from 'react-native';

interface IMyModalProps extends ModalProps {
visible: boolean;
setIsVisible: (visible: boolean) => void;
children: React.ReactNode;
containerStyle?: StyleProp<ViewStyle>;
}
import { Modal, Pressable, StyleSheet } from 'react-native';
import { IMyModalProps } from '@type/Modal';

const MyModal = ({ visible, setIsVisible, children, containerStyle, ...rest }: IMyModalProps) => {
const onClose = () => {
Expand Down
93 changes: 55 additions & 38 deletions src/components/diary/carousel/DiaryCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ import { patchDiary } from '@api/diary/patch';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { snackMessage } from '@stores/snackMessage';
import { tense } from '@stores/tense';
import BasicConfirmModal from '@components/common/BasicConfirmModal';

const DiaryCard = ({ id, createdTime, content, isEditing, setIsEditing }: IDiaryCardProps) => {
const [diaryInput, setDiaryInput] = useState('');
const [timeStartWriting, setTimeStartWriting] = useState<string>('');
const dateStatus = useRecoilValue(tense);
const setSnackbar = useSetRecoilState(snackMessage);
const queryClient = useQueryClient();
const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false);

useEffect(() => {
setDiaryInput(id === NEW_DIARY ? '' : content);
Expand All @@ -28,13 +30,12 @@ const DiaryCard = ({ id, createdTime, content, isEditing, setIsEditing }: IDiary
const addNewDiary = useMutation({
mutationFn: (data: IDiaryPostRequest) => postDiary(data),
onSuccess: (data) => {
queryClient.invalidateQueries({ queryKey: ['diaryCounts'] });
queryClient.invalidateQueries({ queryKey: ['diaryList'] });
queryClient.invalidateQueries({ queryKey: ['diary'] });
setSnackbar('저장이 완료되었습니다.');
setTimeStartWriting('');
},
onError: (error) => {
setSnackbar(error.response.data.message);
setSnackbar(error.response.data.message || '오류가 발생했습니다.');
},
onSettled: () => {
setIsEditing(false);
Expand All @@ -43,27 +44,27 @@ const DiaryCard = ({ id, createdTime, content, isEditing, setIsEditing }: IDiary
const removeDiary = useMutation({
mutationFn: (id: number) => deleteDiary(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['diaryCounts'] });
queryClient.invalidateQueries({ queryKey: ['diaryList'] });
queryClient.invalidateQueries({ queryKey: ['diary'] });
setSnackbar('삭제가 완료되었습니다.');
},
onError: (error) => {
setSnackbar(error.response.data.message);
setSnackbar(error.response.data.message || '오류가 발생했습니다.');
},
onSettled: () => {
setIsEditing(false);
setDiaryInput('');
setIsDeleteModalVisible(false);
},
});
const editDiary = useMutation({
mutationFn: (data: IDiaryPatchRequest) => patchDiary(data),
onSuccess: (data) => {
setTimeStartWriting(data.createdDate);
queryClient.invalidateQueries({ queryKey: ['diaryList'] });
queryClient.invalidateQueries({ queryKey: ['diary', 'list'] });
setSnackbar('수정이 완료되었습니다.');
},
onError: (error) => {
setSnackbar(error.response.data.message);
setSnackbar(error.response.data.message || '오류가 발생했습니다.');
},
onSettled: () => {
setIsEditing(false);
Expand All @@ -78,6 +79,13 @@ const DiaryCard = ({ id, createdTime, content, isEditing, setIsEditing }: IDiary
setSnackbar('수정이 취소되었습니다.');
return;
}
};

const onDelete = () => {
setIsDeleteModalVisible(true);
};

const onConfirmDelete = () => {
removeDiary.mutate(id);
};

Expand Down Expand Up @@ -109,40 +117,49 @@ const DiaryCard = ({ id, createdTime, content, isEditing, setIsEditing }: IDiary
};

return (
<Pressable
style={styles.container}
onPress={onKeyboardDismiss}
disabled={Platform.OS === 'web'}
>
<View style={styles.card}>
<DiaryCardHeader
isNew={id === NEW_DIARY}
createdTime={id !== NEW_DIARY ? createdTime : ''}
timeStartWriting={timeStartWriting}
isEditing={isEditing}
onClose={onClose}
onSave={onSave}
/>
{dateStatus === 'TODAY' ? (
<DiaryInput
id={id}
<>
<Pressable
style={styles.container}
onPress={onKeyboardDismiss}
disabled={Platform.OS === 'web'}
>
<View style={styles.card}>
<DiaryCardHeader
isNew={id === NEW_DIARY}
diaryInput={diaryInput}
setDiaryInput={setDiaryInput}
createdTime={id !== NEW_DIARY ? createdTime : ''}
timeStartWriting={timeStartWriting}
setTimeStartWriting={setTimeStartWriting}
isEditing={isEditing}
setIsEditing={setIsEditing}
placeholder={content}
/>
) : (
<DiaryContent
isEmpty={createdTime === ''}
content={content || '작성된 일기가 없습니다'}
onClose={onClose}
onSave={onSave}
onDelete={onDelete}
/>
)}
</View>
</Pressable>
{dateStatus === 'TODAY' ? (
<DiaryInput
id={id}
isNew={id === NEW_DIARY}
diaryInput={diaryInput}
setDiaryInput={setDiaryInput}
timeStartWriting={timeStartWriting}
setTimeStartWriting={setTimeStartWriting}
isEditing={isEditing}
setIsEditing={setIsEditing}
placeholder={content}
/>
) : (
<DiaryContent
isEmpty={createdTime === ''}
content={content || '작성된 일기가 없습니다'}
/>
)}
</View>
</Pressable>
<BasicConfirmModal
visible={isDeleteModalVisible}
setIsVisible={setIsDeleteModalVisible}
onConfirm={onConfirmDelete}
content="심심기록을 삭제하시겠습니까?"
/>
</>
);
};

Expand Down
4 changes: 3 additions & 1 deletion src/components/diary/carousel/DiaryCardHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface DiaryCardHeaderProps {
isEditing: boolean;
onSave: () => void;
onClose: () => void;
onDelete: () => void;
}

const formatTime = (time: string) => {
Expand All @@ -27,6 +28,7 @@ const DiaryCardHeader = ({
isEditing,
onSave,
onClose,
onDelete,
}: DiaryCardHeaderProps) => {
return (
<View style={styles.header}>
Expand All @@ -43,7 +45,7 @@ const DiaryCardHeader = ({
iconSet="Feather"
name="trash-2"
size={16}
onPress={onClose}
onPress={onDelete}
style={styles.icon}
/>
))}
Expand Down
2 changes: 1 addition & 1 deletion src/components/diary/carousel/DiaryCarousel.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const DiaryCarousel = ({ selectedDate }: IDiaryCarouselProps) => {

useEffect(() => {
setActiveIndex(0);
}, [data]);
}, [selectedDate]);

if (isPending) {
return <CenterViewText text="심심기록을 가져오는 중입니다." />;
Expand Down
4 changes: 3 additions & 1 deletion src/hooks/login/useSendUserToken.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMutation } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { postUserGoogleToken, postUserAppleToken } from '@api/login/post';
import { saveToken } from '@components/login/AuthService';
import { useSetRecoilState } from 'recoil';
Expand All @@ -17,6 +17,7 @@ const useSendUserToken = (loginType: 'google' | 'apple') => {
const setAuthToken = useSetRecoilState(authTokenState);
const setUserInfo = useSetRecoilState(userInfoState);
const setIsLoggedIn = useSetRecoilState(isLoggedInState);
const queryClient = useQueryClient();

const mutationFn = loginType === 'google' ? postUserGoogleToken : postUserAppleToken;

Expand All @@ -31,6 +32,7 @@ const useSendUserToken = (loginType: 'google' | 'apple') => {
onSuccess: async (data) => {
await saveToken(data.accessToken);
setIsLoggedIn(true);
queryClient.resetQueries();
},
onError: (error) => {
console.error(error.response.data.message);
Expand Down
8 changes: 7 additions & 1 deletion src/hooks/setting/settingHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Alert, Linking } from 'react-native';

const useSetting = () => {
const [deleteModalVisible, setDeleteModalVisible] = useState(false);
const { logoutMutation } = useLogout();
const { logoutMutation, deleteAccountMutation } = useLogout();

const onFeedback = async () => {
const url = 'https://forms.gle/nUCrj6JLNCnU8Dez6'; // env에 추가하기
Expand All @@ -20,12 +20,18 @@ const useSetting = () => {
setDeleteModalVisible(true);
};

const onConfirmDeleteAccount = () => {
deleteAccountMutation.mutate();
setDeleteModalVisible(false);
};

const onLogout = () => {
logoutMutation.mutate();
};

return {
deleteModalVisible,
onConfirmDeleteAccount,
setDeleteModalVisible,
onFeedback,
onLogout,
Expand Down
19 changes: 15 additions & 4 deletions src/screens/setting/SettingScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import MyText from '@components/common/MyText';
import { SafeAreaView, StyleSheet, ScrollView, View, Platform } from 'react-native';
import SettingSection from '@components/setting/SettingSection';
import NotiSection from '@components/setting/NotiSection';
import DeleteAccountModal from '@components/setting/DeleteAccountModal';
import useAiPersonaGet from '@hooks/setting/aiPersonaGetHook';
import useNotification from '@hooks/setting/notificationHook';
import useSetting from '@hooks/setting/settingHook';
Expand All @@ -16,10 +15,17 @@ import { ko } from 'date-fns/locale';
import MySnackbar from '@components/common/MySnackbar';
import AiPersonaSelectModal from '@components/setting/AiPersonaSelectModal';
import { userInfoState } from '@stores/login';
import BasicConfirmModal from '@components/common/BasicConfirmModal';

const SettingScreen = () => {
const { deleteModalVisible, setDeleteModalVisible, onFeedback, onLogout, onDeleteAccount } =
useSetting();
const {
deleteModalVisible,
setDeleteModalVisible,
onConfirmDeleteAccount,
onFeedback,
onLogout,
onDeleteAccount,
} = useSetting();
const {
diaryNotiEnabled,
letterNotiEnabled,
Expand Down Expand Up @@ -82,7 +88,12 @@ const SettingScreen = () => {
setIsVisible={setAiPickerVisible}
aiPersonaList={aiPersonaList}
/>
<DeleteAccountModal visible={deleteModalVisible} setIsVisible={setDeleteModalVisible} />
<BasicConfirmModal
visible={deleteModalVisible}
setIsVisible={setDeleteModalVisible}
onConfirm={onConfirmDeleteAccount}
content={`정말로 탈퇴하시겠습니까?\n작성한 모든 심심기록이 지워집니다.`}
/>
<View style={styles.footer}>
<MyText size={11}>심심조각 초판</MyText>
</View>
Expand Down
17 changes: 17 additions & 0 deletions src/types/Modal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { ModalProps, StyleProp, ViewStyle } from 'react-native';

export interface IMyModalProps extends ModalProps {
visible: boolean;
setIsVisible: (visible: boolean) => void;
children: React.ReactNode;
containerStyle?: StyleProp<ViewStyle>;
}

export interface IBasicModalProps {
visible: boolean;
setIsVisible: React.Dispatch<React.SetStateAction<boolean>>;
onConfirm: () => void;
content: string;
confirmText?: string;
}

0 comments on commit 48464e9

Please sign in to comment.