Skip to content

Commit

Permalink
Add. feature/DD-21-기간별 통계 조회
Browse files Browse the repository at this point in the history
  • Loading branch information
jee-eun-k committed Jul 30, 2023
1 parent bfa139b commit 3e462bc
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 60 deletions.
2 changes: 1 addition & 1 deletion src/pages/record/RecordPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ const RecordPage = () => {
);
}}
// dayCellContent={renderDayCellContent}
titleFormat={renderTitle}
titleFormat={renderTitle}
datesSet={(info) => {
getAllRecords(info);
}}
Expand Down
210 changes: 162 additions & 48 deletions src/pages/statistics/Period.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
StatisticsRequest,
} from '@/api/statistics.api';
import { statisticsResultState } from '@/store/statistics';
import { AppBar, Tabs, Tab, Box, Grid, TextField } from '@mui/material';
import { AppBar, Tabs, Tab, Box, Grid, TextField, InputAdornment, IconButton, styled } from '@mui/material';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
Expand All @@ -14,9 +14,7 @@ import localizedFormat from 'dayjs/plugin/localizedFormat';
import 'dayjs/locale/ko';
import { useState, SyntheticEvent, useEffect } from 'react';
import { useRecoilState, useSetRecoilState } from 'recoil';

import WeekPicker from './WeekPicker';

import { selectedStartDate } from '@/store/statistics';

dayjs.extend(utc);
Expand Down Expand Up @@ -45,6 +43,93 @@ const periodTypeList: IPeriodType[] = [
{ title: '일 년', id: 'BY_YEAR' },
];


interface StyledTabProps {
key: string;
label: string;
value: string;
}


/**
* render date input
*/
export const renderDateInput = ({params, width}: any) => {
return (
<TextField
{...params}
helperText={null}
InputProps={{
endAdornment:
<InputAdornment position="end" sx={{m: 0}}>
<IconButton>
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M3.52941 0H4.41176V1.76471H10.5882V0H11.4706V1.76471H14H15V2.76471V13.1176V14.1176H14H1H0V13.1176V2.76471V1.76471H1H3.52941V0ZM10.5882 2.76471V3.52941H11.4706V2.76471H14V6.17647H1V2.76471H3.52941V3.52941H4.41176V2.76471H10.5882ZM1 7.05882V13.1176H14V7.05882H1Z"
fill="#4B4B4B"
/>
</svg>
</IconButton>
</InputAdornment>
}}
sx={{
display: 'flex',
color: '#4B4B4B',
fontWeight: '600',
fontSize: '14px',
' .MuiInputBase-root': { justifyContent: 'center', p: 0 },
' .MuiInputBase-input': { p: '16px 0', flex: '1 1 auto', overflow: 'auto', width: width + 'px' },
' .MuiInputAdornment-root' : {flex: '0 0 auto'},
'& input': { pl: 0 },
'& fieldset': { border: 'none' }
}}
/>
)};

const StyledTabs = styled((props: StyledTabsProps) => (
<Tabs
{...props}
TabIndicatorProps={{
children: <span className="MuiTabs-indicatorSpan" />
}}
/>
))({
height: '55px',
'& .MuiTabs-indicator': {
display: 'flex',
justifyContent: 'center',
backgroundColor: 'transparent',
bottom: '13px',
zIndex: 10
},
'& .MuiTabs-indicatorSpan': {
overflow: 'auto',
backgroundColor: '#FF7184',
borderRadius: '2px',
height: '4px',
width: '31px'
},
});

const StyledTab = styled((props: StyledTabProps) => (
<Tab disableRipple {...props} />
))(({ theme }) => ({
textTransform: 'none',
fontSize: 14,
marginRight: theme.spacing(1),
color: '#949494',
fontWeight: 600,
'&.Mui-selected': {
color: '#FF7184'
},
'&.Mui-focusVisible': {
backgroundColor: 'rgba(100, 95, 228, 0.32)',
},
}));


const Period = () => {
const [periodType, setPeriodType] = useState<PeriodType>(
periodTypeList[0].id,
Expand Down Expand Up @@ -82,80 +167,85 @@ const Period = () => {
};

/**
* returns rendered input
* @param params
* @returns rendered input
* get period string
* @returns period string
*/
const setRenderedInput = (params: any) => {
return (
<TextField
{...params}
helperText={null}
sx={{
'& fieldset': {
border: 'none'

//border: '1px solid red'
},
width: '250px',
border: '1px solid pink'
}}
/>
)};

useEffect(() => {
let date = selectedDate[periodType];
let type: ManipulateType = 'day';
const getPeriodString = (): ManipulateType | undefined => {
switch (periodType) {
case 'BY_MONTH':
type = 'month';
break;
case 'BY_DAY':
return 'day';
case 'BY_WEEK':
type = 'week';
break;
return 'week';
case 'BY_MONTH':
return 'month';
case 'BY_YEAR':
type = 'year';
break;
return 'year';
default:
break;
}
};

useEffect(() => {
let date = selectedDate[periodType];
getStatistics({
fromStartedAt: `${date.format('YYYY-MM-DD')}T00:00:00`,
toFinishedAt: `${date.add(1, type).format('YYYY-MM-DD')}T00:00:00`,
toFinishedAt: `${date.add(1, getPeriodString()).format('YYYY-MM-DD')}T00:00:00`,
});
}, [selectedDate, periodType]);


return (
<LocalizationProvider dateAdapter={AdapterDayjs}>
{/* 날짜 선택 타입 시작 */}
<Box sx={{ bgcolor: 'background.paper' }}>
<Box
sx={{
bgcolor: 'background.paper',
display: 'flex',
flexDirection: 'column',
position: 'relative',
}}
>
<AppBar
position="static"
color="transparent"
elevation={0}
sx={{
boxShadow: '0px 5px 3px 1px rgba(0,0,0,0.05)',
height: 'inherit',
display: 'absolute',
}}
>
<Tabs
<StyledTabs
value={periodType}
onChange={handlePeriodChange}
indicatorColor="secondary"
textColor="inherit"
variant="fullWidth"
aria-label="full width tabs"
aria-label="statistics-category tabs"
indicatorColor="primary"
textColor="primary"
sx={{
height: '100%',
zIndex: 10,
'& .MuiTabs-flexContainer': {
justifyContent: 'center',
},
}}
>
{periodTypeList.map((period, idx) => (
<Tab
<StyledTab
key={'period-selector-' + idx}
label={period.title}
value={period.id}
{...a11yProps(idx)}
/>
))}
</Tabs>
</StyledTabs>
</AppBar>
<Box
sx={{
width: '100%',
height: '70%',
position: 'absolute',
boxShadow: '0px 4px 15px 0px rgba(0,0,0,0.04)',
}}
/>
</Box>
{/* 날짜 선택 타입 끝 */}

Expand All @@ -165,15 +255,27 @@ const Period = () => {
sx={{
direction: 'column',
alignItems: 'center',
justifyContent: 'center',
padding: 1,
justifyContent: 'space-between',
p: '8px 17px',
}}
>
<button
className='fc-next-button fc-button'
style={{ width: '14px', height: '14px' }}
onClick={() => setNewDateRange(selectedDate[periodType].subtract(1, getPeriodString()))}
>
<span
className='fc-icon fc-icon-chevron-left'
style={{ color: '#fff', top: 0, left: 0 }}
/>
</button>

{periodType === 'BY_DAY' && (
<DatePicker
value={selectedDate[periodType].locale('ko')}
inputFormat='MM월 DD일 dddd'
renderInput={setRenderedInput}
renderInput={(params: any) => renderDateInput({params, width: 120})}
disableMaskedInput
onChange={setNewDateRange}
/>
)}
Expand All @@ -188,7 +290,7 @@ const Period = () => {
<DatePicker
value={selectedDate[periodType].locale('ko')}
inputFormat='YYYY년 MM월'
renderInput={setRenderedInput}
renderInput={(params: any) => renderDateInput({params, width: 95})}
onChange={setNewDateRange}
views={['year', 'month']}
openTo='month'
Expand All @@ -198,17 +300,29 @@ const Period = () => {
<DatePicker
value={selectedDate[periodType].locale('ko')}
inputFormat='YYYY년'
renderInput={setRenderedInput}
renderInput={(params: any) => renderDateInput({params, width: 55})}
onChange={setNewDateRange}
views={['year']}
minDate={dayjs('2023-01-01')}
maxDate={dayjs(currDate)}
/>
)}

<button
className='fc-next-button fc-button'
style={{ width: '14px', height: '14px' }}
onClick={() => setNewDateRange(selectedDate[periodType].add(1, getPeriodString()))}
>
<span
className='fc-icon fc-icon-chevron-right'
style={{ color: '#fff', top: 0, left: 0 }}
/>
</button>
</Grid>
{/* 날짜 선택 끝 */}
</LocalizationProvider>
);
};

export default Period;

14 changes: 3 additions & 11 deletions src/pages/statistics/WeekPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { isPropsEqual } from '@fullcalendar/core/internal';
import { TextField } from '@mui/material';
import { styled } from '@mui/material/styles';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { PickersDay, PickersDayProps } from '@mui/x-date-pickers/PickersDay';
import dayjs, { Dayjs } from 'dayjs';
import isBetweenPlugin from 'dayjs/plugin/isBetween';
import weekdayPlugin from 'dayjs/plugin/weekday';
import { renderDateInput } from './Period';

dayjs.extend(isBetweenPlugin);
dayjs.extend(weekdayPlugin);
Expand Down Expand Up @@ -40,7 +40,7 @@ const CustomPickersDay = styled(PickersDay, {


const WeekPicker = ({ value, setValue, onChange }: any): JSX.Element => {

/**
* render the weekpicker date
* @param date
Expand Down Expand Up @@ -83,7 +83,6 @@ const WeekPicker = ({ value, setValue, onChange }: any): JSX.Element => {
const renderDayInputFormat = (value: any) =>
`${value.startOf('week').format('MM월 DD일 dddd')} ~ ${value.endOf('week').format('MM월 DD일 dddd')}`;


return (
<DatePicker
value={value}
Expand All @@ -92,14 +91,7 @@ const WeekPicker = ({ value, setValue, onChange }: any): JSX.Element => {
}}
renderDay={renderWeekPickerDay}
inputFormat={renderDayInputFormat(value)}
renderInput={(params) => (
<TextField
{...params}
sx={{
'& fieldset': { border: 'none' },
}}
/>
)}
renderInput={(params: any) => renderDateInput({params, width: 250})}
/>
);
};
Expand Down

0 comments on commit 3e462bc

Please sign in to comment.