Skip to content

Commit

Permalink
Merge pull request #41 from in63119/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
in63119 authored Apr 26, 2024
2 parents cde63ca + 281f005 commit 5fe9d96
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 62 deletions.
Binary file added Front-end/public/images/institution/icon_check.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 35 additions & 34 deletions Front-end/src/components/institution/RequestKid.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { styled } from 'styled-components';
import fonts from 'constants/fonts';

interface RequestKidProps {
name: string;
Expand All @@ -8,61 +9,61 @@ interface RequestKidProps {
index: number;
}

interface KidContainerProps {
isOdd: boolean;
}

const RequestKid: React.FC<RequestKidProps> = ({ name, gender, birth, index }) => {
const isOdd = (index + 1) % 2 !== 0;

return (
<KidContainer>
<KidIndex>{index + 1}</KidIndex>
<KidContainer isOdd={isOdd}>
<KidInfo>
<KidName>{name}</KidName>
<KidDetails>
<KidBirth>{birth}</KidBirth>
<KidGender>{gender}</KidGender>
</KidDetails>
<KidBirth>{birth}</KidBirth>
<KidGender>{gender}</KidGender>
</KidInfo>
</KidContainer>
);
};

export default RequestKid;

const KidContainer = styled.div`
const KidContainer = styled.div.withConfig({
shouldForwardProp: (prop) => !['isOdd'].includes(prop),
})<KidContainerProps>`
display: flex;
align-items: center;
padding: 10px;
margin: 5px 0;
background-color: #f8f8f8;
border-radius: 8px;
`;

const KidIndex = styled.div`
display: flex;
justify-content: center;
align-items: center;
width: 30px;
height: 30px;
margin-right: 15px;
background-color: #e1e1e1;
border-radius: 50%;
font-weight: bold;
padding: 0 20.5px;
width: 258px;
height: 49px;
background-color: ${(props) => (props.isOdd ? '#ECF5FB' : '#F8F8F8')};
border-radius: 12px;
`;

const KidInfo = styled.div`
flex-grow: 1;
display: flex;
width: 100%;
justify-content: space-between;
`;

const KidName = styled.div`
font-size: 1rem;
font-weight: bold;
margin-bottom: 5px;
`;

const KidDetails = styled.div`
font-size: 0.9rem;
color: #666;
font-family: ${fonts.suit.bold};
font-weight: 500;
font-size: 17px;
line-height: 21.22px;
`;

const KidBirth = styled.span`
margin-right: 10px;
font-family: ${fonts.suit.bold};
font-weight: 500;
font-size: 17px;
line-height: 21.22px;
`;

const KidGender = styled.span``;
const KidGender = styled.span`
font-family: ${fonts.suit.bold};
font-weight: 500;
font-size: 17px;
line-height: 21.22px;
`;
120 changes: 92 additions & 28 deletions Front-end/src/pages/institution/RegistrationRequest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import styled from 'styled-components';
import fonts from 'constants/fonts';
import { RegistrationItem } from 'utils/type';
import { RegistrationItem, GroupedRequests } from 'utils/type';

// DB
import { initialization } from 'db/firestore';
import { query, collection, onSnapshot } from 'firebase/firestore';
import { collection, onSnapshot } from 'firebase/firestore';

// Component
import Header from 'components/Header';
Expand All @@ -24,6 +24,7 @@ const RegistrationRequest = ({ hasGoback = true }) => {
const institution = useRecoilValue(institutionState);
const [realTimeRequest, setRealTimeRequest] = useState<RegistrationItem[]>([]);
const [selectedKids, setSelectedKids] = useState<Set<number>>(new Set());
const [selectAll, setSelectAll] = useState(false);
const navigate = useNavigate();
const db = initialization();

Expand All @@ -43,36 +44,70 @@ const RegistrationRequest = ({ hasGoback = true }) => {
});
};

const toggleSelectAll = () => {
if (selectAll) {
setSelectedKids(new Set());
} else {
const allIndices = new Set(realTimeRequest.map((_, index) => index));
setSelectedKids(allIndices);
}
setSelectAll(!selectAll);
};

const groupedRequests = realTimeRequest.reduce((acc: GroupedRequests, item) => {
const date = `${item.created_at.split(' ')[1]} ${item.created_at.split(' ')[2]}`;
if (!acc[date]) {
acc[date] = [];
}
acc[date].push(item);
return acc;
}, {});

useEffect(() => {
const fetchRealTimeRequests = () => {
const realTimeRequestsQuery = query(collection(db, 'institution', institution.name, 'RegistrationRequest'));
onSnapshot(realTimeRequestsQuery, (snapshot) => {
const realTimeRequestList = snapshot.docs.map((doc) => {
const { birth, gender, institution, name } = doc.data();
console.log(doc.data());
return { birth, gender, institution, name };
});
setRealTimeRequest(realTimeRequestList);
const realTimeRequestsRef = collection(db, 'institution', institution.name, 'RegistrationRequest');
const unsubscribe = onSnapshot(realTimeRequestsRef, (snapshot) => {
const realTimeRequestList = snapshot.docs.map((doc) => {
const { birth, gender, institution, name, created_at } = doc.data() as RegistrationItem;
const time = created_at.split(' ')[3];
return { birth, gender, institution, name, created_at, time };
});
};
setRealTimeRequest(realTimeRequestList);
});

fetchRealTimeRequests();
return () => unsubscribe();
}, [db, institution.name]);

useEffect(() => {
if (selectAll && realTimeRequest.length && selectedKids.size !== realTimeRequest.length) {
setSelectAll(false);
}
}, [realTimeRequest, selectAll, selectedKids]);

return (
<Container>
<HeaderContainer>
<Header hasGoback={hasGoback} handleClickGoBack={goBackHandler} />
<Title>등록 요청 확인</Title>
</HeaderContainer>
{realTimeRequest.length === 0
? null
: realTimeRequest?.map((kid: RegistrationItem, i: number) => (
<SelectionAll onClick={toggleSelectAll}>
{selectAll ? (
<Check src="/images/institution/icon_check.png" alt="Check" />
) : (
<NotCheck src="/images/institution/icon_check_empty.png" alt="NotCheck" />
)}
전체 선택({selectedKids.size}/{realTimeRequest.length})
</SelectionAll>
{Object.entries(groupedRequests).map(([date, kids]) => (
<React.Fragment key={date}>
<DateTitle>{date}</DateTitle>
{kids.map((kid, i) => (
<KidContainer key={i} selected={selectedKids.has(i)} onClick={() => toggleSelection(i)}>
<RequestKid name={kid.name} gender={kid.gender} birth={kid.birth} index={i} />
<SelectionIndicator selected={selectedKids.has(i)} />
<RequestKidTime>{kid.time}</RequestKidTime>
</KidContainer>
))}
</React.Fragment>
))}
</Container>
);
};
Expand Down Expand Up @@ -108,21 +143,50 @@ const HeaderContainer = styled.div`
const KidContainer = styled.div<StyledSelected>`
display: flex;
align-items: center;
background-color: ${({ selected }) => (selected ? '#E0F7FA' : 'transparent')};
transition: background-color 0.3s;
cursor: pointer;
&:hover {
background-color: #e0f7fa;
&::before {
content: '';
display: block;
width: 24px;
height: 24px;
margin-right: 10px;
background: url(${(props) =>
props.selected ? '/images/institution/icon_check.png' : '/images/institution/icon_check_empty.png'})
no-repeat center center;
background-size: contain;
}
`;

const SelectionIndicator = styled.div<StyledSelected>`
width: 20px;
height: 20px;
border: 2px solid #009688;
border-radius: 50%;
margin-left: auto;
background-color: ${({ selected }) => (selected ? '#009688' : 'transparent')};
transition: background-color 0.3s;
const DateTitle = styled.div`
font-family: ${fonts.suit.bold};
font-weight: 600;
font-size: 14px;
line-height: 17.47px;
padding: 8px 20px 8px 20px;
`;

const SelectionAll = styled.div`
font-family: ${fonts.suit.bold};
font-weight: 400;
font-size: 14px;
line-height: 17.47px;
`;

const NotCheck = styled.img`
width: 24px;
height: 24px;
`;

const Check = styled.img`
width: 24px;
height: 24px;
`;

const RequestKidTime = styled.div`
font-family: ${fonts.suit.bold};
font-weight: 500;
font-size: 11px;
line-height: 13.73px;
`;
16 changes: 16 additions & 0 deletions Front-end/src/utils/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const formatData = () => {
const date = new Date();

const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();

const formattedMonth = `${month}`;
const formattedDay = `${day}`;
const formattedHours = hours < 10 ? `0${hours}` : `${hours}`;
const formattedMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`;

return `${year}${formattedMonth}${formattedDay}${formattedHours}:${formattedMinutes}`;
};
6 changes: 6 additions & 0 deletions Front-end/src/utils/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,10 @@ export interface RegistrationItem {
institution: string;
isRegistered?: boolean;
name: string;
created_at: string;
time: string;
}

export type GroupedRequests = {
[key: string]: RegistrationItem[];
};

0 comments on commit 5fe9d96

Please sign in to comment.