Skip to content

Commit

Permalink
feat/#24 Calendar 완료
Browse files Browse the repository at this point in the history
  • Loading branch information
ShinKwang2 committed Jul 2, 2024
1 parent 4477146 commit 3d07111
Show file tree
Hide file tree
Showing 20 changed files with 361 additions and 404 deletions.
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
"react-calendar": "^5.0.0",
"react-dom": "^18.3.1",
"react-icons": "^5.2.1",
"react-kakao-maps-sdk": "^1.1.27",
"react-router-dom": "^6.24.0",
"swiper": "^11.1.4",
"react-kakao-maps-sdk": "^1.1.27"
"react-time-picker": "^7.0.0",
"react-time-picker-typescript": "^1.2.3",
"swiper": "^11.1.4"
},
"devDependencies": {
"@types/react": "^18.3.3",
Expand Down
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function App() {
element={<AttendanceEdit />}
/>
</Route>
<Route path='/owner-calendar' element={<OwnerCalendarPage />} />
{/* <Route path='/owner-calendar' element={<OwnerCalendarPage />} /> */}
<Route path='/part-time/*' element={<PaymentMain />}>
<Route path='worktime' element={<WorkTime />} />
<Route path='payment' element={<Payment />} />
Expand Down
135 changes: 114 additions & 21 deletions src/components/calendar-owner/AttendanceEdit.tsx
Original file line number Diff line number Diff line change
@@ -1,71 +1,164 @@
import { useState } from 'react';
import { ChangeEvent, useState } from 'react';
import { useAttendance } from '../../contexts/Attendance-Context';
import InputBox from '../ui/InputBox';
import { VStack } from '../ui/Stack';
import { Spacer, VStack } from '../ui/Stack';
import TimeBox from './TimeBox';
import WorkPlaceName from '../ui/WorkPlaceName';
import SelectOptions from './SelectOptions';
import Select from './Select';
import { getTimeString } from '../../utils/get-TimeString';
import { MINIMUM_PAY_PER_HOUR } from '../../utils/const-value';
import BtnBottom from '../BtnBottom';
import ModalCenter from '../ModalCenter';
import { useNavigate } from 'react-router-dom';

const mockData = [
{
workPlaceId: 1, // Long
workPlaceNm: '롯데리아 자양점',
workPlaceColor: '01', // String
workPlaceEmployeeId: 1, // Long
workPlaceEmployeeId: 10, // Long
employeeNm: '이신광', // String
},
{
workPlaceId: 1, // Long
workPlaceNm: '롯데리아 자양점',
workPlaceColor: '01', // String
workPlaceEmployeeId: 2, // Long
workPlaceEmployeeId: 12, // Long
employeeNm: '이서하', // String
},
{
workPlaceId: 1, // Long
workPlaceNm: '롯데리아 자양점',
workPlaceColor: '01',
workPlaceEmployeeId: 3, // Long
workPlaceEmployeeId: 13, // Long
employeeNm: '정연주', // String
},
{
workPlaceId: 2, // Long
workPlaceNm: '버거킹',
workPlaceColor: '02', // String
workPlaceEmployeeId: 4, // Long
workPlaceEmployeeId: 14, // Long
employeeNm: '고영우', // String
},
{
workPlaceId: 2, // Long
workPlaceNm: '버거킹',
workPlaceColor: '02', // String
workPlaceEmployeeId: 5, // Long
workPlaceEmployeeId: 18, // Long
employeeNm: '최은진', // String
},
];

const AttendanceEdit = () => {
const [workEmployeeList, setWorkEmployeeList] = useState(mockData);
const navigation = useNavigate();

const [workEmployeeList] = useState(mockData); // 나의 전체 사업장의 전 직원들

const { attendance, changeAttendance } = useAttendance();
const [employeeId, setEmployeeId] = useState(attendance?.workPlaceEmployeeId);
const [startTime, setStartTime] = useState(attendance?.startTime);
const [endTime, setEndTime] = useState(attendance?.endTime);
const [workPlaceEmployeeId, setWorkPlaceEmployeeId] = useState(
attendance?.workPlaceEmployeeId
);
const [startTime, setStartTime] = useState<Date | undefined>(
attendance?.startTime
);
const [endTime, setEndTime] = useState<Date | undefined>(attendance?.endTime);
const [restMinutes, setRestMinutes] = useState(attendance?.restMinutes);
const [payPerHour, setPayPerHour] = useState(attendance?.payPerHour);

console.log(attendance);
const dateUrl = startTime!.toLocaleDateString('en-CA');

// 모달 관련
const [isModalOpen, setModalOpen] = useState(false);

const onSelectWorkEmployeeId = (id: number) => {
setWorkPlaceEmployeeId(id);
};

const onChangePayPerHour = (e: ChangeEvent<HTMLInputElement>) => {
if (Number(e.target.value) <= MINIMUM_PAY_PER_HOUR) {
e.target.value = `${MINIMUM_PAY_PER_HOUR}`;
}
setPayPerHour(Number(e.target.value));
};

const updateTime = (
date: Date | undefined,
time: string
): Date | undefined => {
if (!date) return undefined;
const [hours, minutes] = time.split(':').map(Number);
const newDate = new Date(date);
newDate.setHours(hours, minutes);
return newDate;
};

return (
<VStack className='px-6 py-10 gap-6'>
<InputBox label='근무자명'>
<Select options={workEmployeeList} />
</InputBox>
<InputBox label='근무 시간'>
<TimeBox />
</InputBox>
<InputBox label='시급' value={String(payPerHour)} />
</VStack>
<>
{isModalOpen && (
<ModalCenter
title={' '}
closeModal={() => setModalOpen(false)}
hasDecline
confirmAction={() => navigation(`/owner/calendar/${dateUrl}`)}
>{`정말로 수정하시겠습니까?`}</ModalCenter>
)}

<VStack className='px-6 py-10 gap-6'>
<InputBox label='근무자명'>
<Select
options={workEmployeeList}
selectedId={workPlaceEmployeeId!}
onSelect={onSelectWorkEmployeeId}
/>
</InputBox>
<InputBox label='근무 시간'>
<TimeBox
startTime={getTimeString(attendance!.startTime)}
changeStartTime={(time: string) =>
setStartTime(updateTime(startTime, time))
}
endTime={getTimeString(attendance!.endTime)}
changeEndTime={(time: string) =>
setEndTime(updateTime(endTime, time))
}
restMinutes={restMinutes!}
changeRestMinutes={(minutes: number) => setRestMinutes(minutes)}
/>
</InputBox>
<InputBox
label='시급'
value={String(payPerHour)}
onChange={onChangePayPerHour}
/>

<div className='text-gray-400 text-sm'>
현재 최저시급은
<span className='underline'>{`${MINIMUM_PAY_PER_HOUR}`}</span>
이에요..
</div>
<div className='text-gray-400 text-sm'>
근무 시간이 4시간 이상이면 30분 이상, <br />
8시간 이상이면 1시간 이상 휴게시간이 필요해요. <br /> (근로기준법
54조)
</div>

<Spacer />
<BtnBottom
text='근무 수정'
action={() => {
changeAttendance({
workPlaceEmployeeId: workPlaceEmployeeId!,
payPerHour: payPerHour!,
startTime: startTime!,
endTime: endTime!,
restMinutes: restMinutes!,
});
setModalOpen(true);
}}
/>
</VStack>
</>
);
};
export default AttendanceEdit;
14 changes: 5 additions & 9 deletions src/components/calendar-owner/DateDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ const onClickChangeAttendance = (data: DateWorkDetail) => {
payPerHour: data.payPerHour,
startTime: data.startTime,
endTime: data.endTime,
restStartTime: new Date(),
restEndTime: new Date(),
restMinutes: data.restMinutes,
};
};

Expand All @@ -41,15 +40,13 @@ const DateDetail = () => {
const targetDate = new Date(date!);

const temp = getFilteredData(targetDate);
console.log(temp);
// console.log(temp);

return (
<div className='px-6'>
<h2>Selected Date: {date}</h2>

<div className='px-6 py-7'>
<VStack className='gap-3'>
<HStack className='justify-between items-center'>
<div>총 근무 시간: 8시간</div>
<div>총 근무 시간: 8시간 이거 꼭 바꿔야함</div>
<button className='bg-hanaLightGreen gap-2 py-1 px-2 flex items-center rounded-lg text-white'>
<AiOutlinePlusCircle />
<div>근무 추가</div>
Expand All @@ -66,8 +63,7 @@ const DateDetail = () => {
payPerHour: item.payPerHour,
startTime: item.startTime,
endTime: item.endTime,
restStartTime: new Date(),
restEndTime: new Date(),
restMinutes: item.restMinutes,
}),
onClickEditAttendance(item.attendanceId);
}}
Expand Down
37 changes: 20 additions & 17 deletions src/components/calendar-owner/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,26 @@ import WorkPlaceName from '../ui/WorkPlaceName';
import SelectBox from './SelectBox';
import { useState } from 'react';

type optionView = {
workPlaceId: number;
workPlaceNm: string;
workPlaceColor: string;
workPlaceEmployeeId: number;
employeeNm: string;
};
type SelectProps = {
options: [];
options: optionView[];
selectedId: number;
onSelect: (id: number) => void;
};

const Select = ({ options }: SelectProps) => {
const [selected, setSelected] = useState({
workPlaceId: 1, // Long
workPlaceNm: '롯데리아 자양점',
workPlaceColor: '01', // String
workPlaceEmployeeId: 1, // Long
employeeNm: '이신광', // String
});
const [showList, setShowList] = useState(false);
const filteredData = (options: optionView[], selectedId: number) => {
return options.find((e) => e.workPlaceEmployeeId === selectedId);
};

const onClickSelect = (data) => {
setSelected(data);
};
const Select = ({ options, selectedId, onSelect }: SelectProps) => {
const [showList, setShowList] = useState(false);
const selected = filteredData(options, selectedId);

return (
<div className='w-full'>
Expand All @@ -29,18 +32,18 @@ const Select = ({ options }: SelectProps) => {
>
<div className='w-1/2 px-1 py-2'>
<WorkPlaceName
name={selected.workPlaceNm}
colorType={selected.workPlaceColor}
name={selected!.workPlaceNm}
colorType={selected!.workPlaceColor}
/>
</div>
<div className='w-1/2'>{selected.employeeNm}</div>
<div className='w-1/2 font-bold'>{selected!.employeeNm}</div>
<FaAngleDown />
</button>
<SelectBox
isOpen={showList}
options={options}
onClose={() => setShowList(false)}
onClick={onClickSelect}
onClick={onSelect}
/>
</div>
);
Expand Down
8 changes: 4 additions & 4 deletions src/components/calendar-owner/SelectBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,20 @@ type SelectBoxProps = {
employeeNm: string;
}[];
onClose: () => void;
onClick: (data) => void;
onClick: (id: number) => void;
};

const SelectBox = ({ isOpen, options, onClose, onClick }: SelectBoxProps) => {
if (!isOpen) return null;

return (
<div className='w-full border overflow-y-scroll rounded-b-xl'>
<VStack>
<div className='w-full h-full border rounded-b-xl'>
<VStack className='h-40 overflow-scroll '>
{options.map((data) => (
<button
key={data.workPlaceEmployeeId}
onClick={() => {
onClick(data);
onClick(data.workPlaceEmployeeId);
onClose();
}}
className='bg-white'
Expand Down
Loading

0 comments on commit 3d07111

Please sign in to comment.