Skip to content

Commit

Permalink
Merge pull request #102 from DearMyPeace/SS-26-FE-report-android
Browse files Browse the repository at this point in the history
feat: 리포트 창 수정사항 반영(Web)
  • Loading branch information
chanhihi authored Dec 1, 2024
2 parents d2806d0 + e2ccbf5 commit 228493a
Show file tree
Hide file tree
Showing 23 changed files with 778 additions and 67 deletions.
57 changes: 52 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@
"react-native-element-dropdown": "^2.12.1",
"react-native-encrypted-storage": "^4.0.3",
"react-native-gesture-handler": "^2.16.2",
"react-native-gifted-charts": "^1.4.47",
"react-native-linear-gradient": "^2.8.3",
"react-native-markdown-display": "^7.0.2",
"react-native-paper": "^5.12.3",
"react-native-reanimated": "^3.12.1",
"react-native-safe-area-context": "^4.10.5",
"react-native-screens": "^3.31.1",
"react-native-svg": "^15.3.0",
"react-native-svg": "^15.9.0",
"react-native-web": "^0.19.12",
"recoil": "^0.7.7",
"sha256": "^0.2.0"
Expand Down
51 changes: 50 additions & 1 deletion src/api/report/get.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import instance from '@api/axios';
import { DayEmotionData, EmotionData } from '@type/IReport';
import { DayEmotionData, EmotionData, IReportContent, IReportData } from '@type/IReport';

export const fetchWeekReport = async (targetDate: string): Promise<EmotionData> => {
const response = await instance.get(`/report/week?targetDate=${targetDate}`);
Expand All @@ -10,3 +10,52 @@ export const fetchReportPNN = async (targetDate: string): Promise<DayEmotionData
const response = await instance.get(`/report/week/${targetDate}`);
return response.data;
};

const mockReportData = [
{
rate: 0.3,
keyword: '건강',
content:
'날씨가 추워질수록 건강에 대한 언급이 많아졌어요. 다음주부터는 더 춥다고 하니, 따뜻하게 입는다면 건강에 대한 걱정이 덜 할 것 같아요.',
},
{
rate: 0.2,
keyword: '영화',
content: '영화를 보는 것은 영화를 보는 것이 아니라 영화를 보는 것입니다.',
},
{
rate: 0.15,
keyword: '날씨',
content:
'날씨가 추워질수록 건강에 대한 언급이 많아졌어요. 다음주부터는 더 춥다고 하니, 따뜻하게 입는다면 건강에 대한 걱정이 덜 할 것 같아요.',
},
{
rate: 0.15,
keyword: '요리하다',
content: '요리하다는 것은 요리하는 것이 아니라 요리하는 것입니다.',
},
{
rate: 0.1,
keyword: '독서',
content: '독서는 독서하는 것이 아니라 독서하는 것입니다.',
},
];

export const fetchMockReportData = async (targetDate: string): Promise<IReportData[]> => {
console.log(`fetchMockReportData: ${targetDate}`);
return mockReportData;
};

export const fetchMockReportKeyword = async ({
targetDate,
rank,
}: {
targetDate: string;
rank: number;
}): Promise<IReportContent> => {
console.log(`fetchMockReportKeyword: ${targetDate}, ${rank}`);
return {
keyword: mockReportData[rank - 1].keyword,
content: mockReportData[rank - 1].content,
};
};
25 changes: 25 additions & 0 deletions src/components/common/MyPressable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React, { ReactNode } from 'react';
import { Pressable, PressableProps, ViewStyle } from 'react-native';

interface IMyPressableProps extends PressableProps {
children: ReactNode;
containerStyle?: ViewStyle;
}

function MyPressable({ children, containerStyle, ...pressableProps }: IMyPressableProps) {
return (
<Pressable
{...pressableProps}
style={(state) => [
state.pressed && { opacity: 0.5 },
state.hovered && { backgroundColor: 'rgba(31, 27, 21, 0.06)' },
!pressableProps.onPress && { cursor: 'default' },
containerStyle,
]}
>
{children}
</Pressable>
);
}

export default MyPressable;
16 changes: 11 additions & 5 deletions src/components/diary/calendar/CalendarArrow.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
import React from 'react';
import { View } from 'react-native';
import { StyleProp, View, ViewStyle } from 'react-native';
import Left from '@assets/svg/icons/entypo--chevron-small-left.svg';
import Right from '@assets/svg/icons/entypo--chevron-small-right.svg';

export type Direction = 'left' | 'right';

interface CalendarArrowProps {
direction: Direction;
size?: number;
style?: StyleProp<ViewStyle>;
}

const CalendarArrow = ({ direction }: CalendarArrowProps) => {
const CalendarArrow = ({
direction,
size = 24,
style = { marginRight: 20 },
}: CalendarArrowProps) => {
return (
<View style={direction === 'left' && { marginRight: 20 }}>
<View style={direction === 'left' && style}>
{direction === 'left' ? (
<Left width={24} height={24} fill="#333333" />
<Left width={size} height={size} fill="#333333" />
) : (
<Right width={24} height={24} fill="#333333" />
<Right width={size} height={size} fill="#333333" />
)}
</View>
);
Expand Down
18 changes: 10 additions & 8 deletions src/components/diary/calendar/CalendarHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React from 'react';
import { View, StyleSheet } from 'react-native';
import MyText from '@components/common/MyText';
import TextButton from '@components/common/TextButton';
Expand All @@ -9,16 +9,20 @@ import { selectedDateStatus, tense } from '@stores/tense';
import { fontLarge } from '@utils/Sizing';
import TodayButton from '@components/common/TodayButton';
import { getToday } from '@utils/dateUtils';
import useCalendarModal from '@hooks/common/useCalendarModal';

const CalendarHeader = ({ date }: { date: string }) => {
const dateState = useRecoilValue(tense);
const [isModalVisible, setModalVisible] = useState(false);
const [selectedDate, setSelectedDate] = useRecoilState(selectedDateStatus);
const [selectedMonth, setSelectedMonth] = useState(parseInt(selectedDate.slice(5, 7), 10));
const [selectedYear, setSelectedYear] = useState(parseInt(selectedDate.slice(0, 4), 10));
const { isModalVisible, setModalVisible, selectedModalDate, setSelectedModalDate } =
useCalendarModal({
month: parseInt(selectedDate.slice(5, 7), 10),
year: parseInt(selectedDate.slice(0, 4), 10),
});

const handleModalDismiss = () => {
const day = selectedDate.slice(8, 10);
const { year: selectedYear, month: selectedMonth } = selectedModalDate;
const lastDay = new Date(selectedYear, selectedMonth, 0).getDate();
const month = selectedMonth.toString().padStart(2, '0');
if (parseInt(day, 10) > lastDay) {
Expand Down Expand Up @@ -52,10 +56,8 @@ const CalendarHeader = ({ date }: { date: string }) => {
<CalendarSelectModal
isModalVisible={isModalVisible}
handleModalDismiss={handleModalDismiss}
selectedMonth={selectedMonth}
selectedYear={selectedYear}
setSelectedMonth={setSelectedMonth}
setSelectedYear={setSelectedYear}
selectedModalDate={selectedModalDate}
setSelectedModalDate={setSelectedModalDate}
/>
</View>
);
Expand Down
56 changes: 34 additions & 22 deletions src/components/diary/calendar/CalendarSelectModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,59 @@ import {
StyleSheet,
ScrollView,
} from 'react-native';
import { ICalendarModalDate } from '@type/Diary';

interface IMonthItem {
month: string;
index: number;
displayedMonth: string;
month: number;
}

interface ICalendarSelectModalProps {
isModalVisible: boolean;
handleModalDismiss: () => void;
selectedMonth: number;
selectedYear: number;
setSelectedMonth: (month: number) => void;
setSelectedYear: (year: number) => void;
selectedModalDate: ICalendarModalDate;
setSelectedModalDate: (date: ICalendarModalDate) => void;
}

const CalendarSelectModal = ({
isModalVisible,
handleModalDismiss,
selectedMonth,
selectedYear,
setSelectedMonth,
setSelectedYear,
selectedModalDate,
setSelectedModalDate,
}: ICalendarSelectModalProps) => {
const monthScrollRef = useRef<ScrollView>(null);
const yearScrollRef = useRef<ScrollView>(null);

const monthItemHeight = 49;
const yearItemHeight = 49;

const renderMonthItem = ({ month, index }: IMonthItem) => (
<Pressable key={index} style={styles.modalItem} onPress={() => setSelectedMonth(index + 1)}>
<View style={selectedMonth === index + 1 ? styles.selectedStyle : null}>
<MyText style={selectedMonth === index + 1 ? styles.selectedText : styles.modalText}>
{month}
const renderMonthItem = ({ displayedMonth, month }: IMonthItem) => (
<Pressable
key={displayedMonth}
style={styles.modalItem}
onPress={() => setSelectedModalDate({ ...selectedModalDate, month })}
>
<View style={selectedModalDate.month === month ? styles.selectedStyle : null}>
<MyText style={selectedModalDate.month === month ? styles.selectedText : styles.modalText}>
{displayedMonth}
</MyText>
</View>
</Pressable>
);

const renderYearItem = (year: number) => (
<Pressable key={year} style={styles.modalItem} onPress={() => setSelectedYear(year)}>
<View style={selectedYear === year ? styles.selectedStyle : null}>
<MyText style={selectedYear === year ? styles.selectedText : styles.modalText}>
<Pressable
key={year}
style={styles.modalItem}
onPress={() =>
setSelectedModalDate({
...selectedModalDate,
year,
})
}
>
<View style={selectedModalDate.year === year ? styles.selectedStyle : null}>
<MyText style={selectedModalDate.year === year ? styles.selectedText : styles.modalText}>
{year}
</MyText>
</View>
Expand All @@ -62,12 +72,12 @@ const CalendarSelectModal = ({

useEffect(() => {
if (isModalVisible) {
const monthOffset = (selectedMonth - 1) * monthItemHeight - 120;
const yearOffset = (selectedYear - 2000) * yearItemHeight - 120;
const monthOffset = (selectedModalDate.month - 1) * monthItemHeight - 120;
const yearOffset = (selectedModalDate.year - 2000) * yearItemHeight - 120;
monthScrollRef.current?.scrollTo({ y: monthOffset, animated: true });
yearScrollRef.current?.scrollTo({ y: yearOffset, animated: true });
}
}, [isModalVisible, selectedMonth, selectedYear]);
}, [isModalVisible, selectedModalDate]);

return (
<Modal visible={isModalVisible} transparent={true} animationType="fade">
Expand All @@ -80,7 +90,9 @@ const CalendarSelectModal = ({
style={styles.modalMonth}
showsVerticalScrollIndicator={false}
>
{kMonth.map((month, index) => renderMonthItem({ month, index }))}
{kMonth.map((displayedMonth, index) =>
renderMonthItem({ displayedMonth, month: index + 1 }),
)}
</ScrollView>
<ScrollView
ref={yearScrollRef}
Expand Down
16 changes: 16 additions & 0 deletions src/hooks/common/useCalendarModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useState } from 'react';
import { ICalendarModalDate } from '@type/Diary';

const useCalendarModal = ({ month, year }: ICalendarModalDate) => {
const [isModalVisible, setModalVisible] = useState(false);
const [selectedModalDate, setSelectedModalDate] = useState<ICalendarModalDate>({ month, year });

return {
isModalVisible,
setModalVisible,
selectedModalDate,
setSelectedModalDate,
};
};

export default useCalendarModal;
Loading

0 comments on commit 228493a

Please sign in to comment.