Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0f22b85
refactor: API 에러 메시지 형식 변경
seungw0o Nov 17, 2025
1ecb0b5
refactor: 에러 메세지 형식 변경
seungw0o Nov 18, 2025
9460173
style: DetailBox MateList 스타일 변경
seungw0o Nov 19, 2025
bcb6d24
feat: Main 페이지 Skeleton 추가
seungw0o Nov 19, 2025
ff73260
feat: Home 페이지 DetailBox 로딩 상태 개선
seungw0o Nov 20, 2025
3fd72ed
feat: MyPage Skeleton 추가
seungw0o Nov 24, 2025
c1cfe0c
chore: 파일 이동
seungw0o Nov 26, 2025
5c38cf6
feat: 공지사항 페이지 Skeleton 추가
seungw0o Nov 27, 2025
45663d7
feat: 설문(투표) 페이지 Skeleton 추가
seungw0o Nov 28, 2025
99f81b3
feat: 설문 페이지 관련 pathToKorean 객체 추가
seungw0o Nov 28, 2025
13c22e6
feat: 봉사활동 관리 기능 추가
seungw0o Nov 29, 2025
6ab3ba1
refactor: Skeleton 컴포넌트 Props 제거 및 count 상수화
seungw0o Nov 29, 2025
ee2f09c
refactor: StudentInfo 컴포넌트에서 API 호출 및 Toast 제거
seungw0o Nov 30, 2025
61843cc
feat: 봉사활동 목록 Skeleton 추가
seungw0o Nov 30, 2025
3337dff
feat: 봉사활동 상세 페이지 Skeleton 추가
seungw0o Nov 30, 2025
13ec2ff
feat: 봉사활동 신청 관리 페이지 Skeleton 추가 및 API 연동
seungw0o Nov 30, 2025
a1f4ac8
feat: 봉사활동 상세 페이지에 Empty State 추가
seungw0o Nov 30, 2025
48ba93a
refactor: DetailBoxSkeleton 컴포넌트 StudentDetailSkeleton으로 이름 변경
seungw0o Dec 1, 2025
f9df11c
refactor: Home Skeleton 컴포넌트 export 방식 변경 및 불필요 코드 제거
seungw0o Dec 1, 2025
5df5dbe
feat: 잔류 신청 관리 페이지 Skeleton 추가
seungw0o Dec 1, 2025
1d27c8a
feat: RecentPointItem에 Skeleton 추가
seungw0o Dec 2, 2025
74449fe
refactor: 불필요한 Skeleton 컴포넌트 및 코드 제거
seungw0o Dec 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions services/admin/src/apis/volunteers/response.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { SexType } from './request';

export interface getVolunteersResponse {
volunteers: volunteer[];
}
Expand All @@ -9,7 +11,7 @@ export interface volunteer {
point: number;
optional_point: number;
max_applicants: number;
available_sex: string;
available_sex: SexType;
available_grade: string;
current_applicants: number;
}
Expand All @@ -30,7 +32,8 @@ export interface getVolunteerCurrentResponse {

export interface currentVolunteer {
name: string;
available_sex: string;
id: string;
available_sex: SexType;
available_grade: string;
current_applicants: number;
max_applicants: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import styled from 'styled-components';
import { Skeleton } from '../Skeleton';

export function StudentDetailSkeleton() {
return (
<_DetailBox>
<_ProfileSection>
<Skeleton variant="circular" width="100px" height="100px" />
<_ProfileInfo>
<_NameContainer>
<Skeleton width="61px" height="34px" />
<Skeleton width="51px" height="34px" />
</_NameContainer>
<_RoomContainer>
<Skeleton width="48px" height="28px" />
<Skeleton width="60px" height="30px" borderRadius="24px" />
</_RoomContainer>
</_ProfileInfo>
</_ProfileSection>

<_PointWrapper>
<Skeleton width="172px" height="47px" borderRadius="4px" />
<Skeleton width="172px" height="47px" borderRadius="4px" />
</_PointWrapper>

<_Section>
<Skeleton width="85px" height="22px" />
<_MateList>
{Array.from({ length: 3 }).map((_, index) => (
<Skeleton
key={index}
width="80px"
height="50px"
borderRadius="4px"
/>
))}
</_MateList>
</_Section>

<_Section>
<Skeleton width="56px" height="22px" />
<_MateList>
{Array.from({ length: 2 }).map((_, index) => (
<Skeleton
key={index}
width="80px"
height="26px"
borderRadius="13px"
/>
))}
</_MateList>
</_Section>

<_Section>
<Skeleton width="44px" height="22px" />
<_PointList>
{Array.from({ length: 5 }).map((_, index) => (
<Skeleton
key={index}
width="357px"
height="50px"
borderRadius="4px"
/>
))}
</_PointList>
</_Section>
</_DetailBox>
);
}

const _NameContainer = styled.div`
display: flex;
gap: 16px;
align-items: center;
`;
const _RoomContainer = styled.div`
display: flex;
gap: 24px;
align-items: center;
`;

const _DetailBox = styled.div`
position: relative;
margin-top: 43px;
padding: 60px 40px;
width: 436px;
min-height: 485px;
display: flex;
flex-direction: column;
box-shadow: 0px 1px 20px rgba(238, 238, 238, 0.8);
border-radius: 4px;
overflow: scroll;
gap: 40px;
`;

const _ProfileSection = styled.div`
display: flex;
align-items: center;
gap: 24px;
`;

const _ProfileInfo = styled.div`
display: flex;
flex-direction: column;
gap: 10px;
`;

const _PointWrapper = styled.div`
display: flex;
gap: 12px;
`;

const _Section = styled.div`
display: flex;
flex-direction: column;
gap: 10px;
`;

const _MateList = styled.div`
display: flex;
gap: 8px;
flex-wrap: wrap;
`;

const _PointList = styled.div`
display: flex;
flex-direction: column;
gap: 12px;
margin-top: 12px;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import styled from 'styled-components';
import { Skeleton } from '../Skeleton';

export function StudentListSkeleton() {
return (
<_Wrapper>
<_Filter>
<Skeleton width="241px" height="44px" borderRadius="30px" />
<_Buttons>
<_ButtonContainer>
<Skeleton width="116px" height="50px" borderRadius="4px" />
<Skeleton width="77px" height="50px" borderRadius="4px" />
<Skeleton width="116px" height="50px" borderRadius="4px" />
<Skeleton width="99px" height="50px" borderRadius="4px" />
</_ButtonContainer>
<_Divider />
<Skeleton width="106px" height="50px" borderRadius="4px" />
</_Buttons>
</_Filter>

<_Container>
<_SelectAllSection>
<Skeleton width="24px" height="24px" />
<Skeleton width="56px" height="22px" />
</_SelectAllSection>

<_StudentList>
{Array.from({ length: 8 }).map((_, index) => (
<StudentBoxSkeleton key={index} />
))}
</_StudentList>
</_Container>
</_Wrapper>
);
}

function StudentBoxSkeleton() {
return (
<_StudentBoxWrapper>
<_LeftSection>
<Skeleton width="24px" height="24px" />
<Skeleton variant="circular" width="36px" height="36px" />
<Skeleton width="50px" height="28px" />
<Skeleton width="42px" height="28px" />
</_LeftSection>

<_CenterSection>
<Skeleton width="45px" height="26px" borderRadius="12px" />
<Skeleton width="45px" height="26px" borderRadius="12px" />
</_CenterSection>

<_RightSection>
<Skeleton width="48px" height="25px" />
</_RightSection>
</_StudentBoxWrapper>
);
}

const _Container = styled.div`
display: flex;
flex-direction: column;
gap: 27px;
`;

const _Wrapper = styled.div`
width: 1030px;
display: flex;
flex-direction: column;
gap: 52px;
`;

const _ButtonContainer = styled.div`
display: flex;
align-items: center;
gap: 8px;
`;

const _Filter = styled.section`
display: flex;
justify-content: space-between;
align-items: center;
`;

const _Buttons = styled.div`
display: flex;
align-items: center;
gap: 16px;
`;

const _Divider = styled.div`
width: 2px;
height: 47px;
background-color: ${({ theme }) => theme.color.gray2 || '#e0e0e0'};
`;

const _SelectAllSection = styled.div`
display: flex;
align-items: center;
gap: 16px;
margin-left: 22px;
`;

const _StudentList = styled.ul`
display: flex;
flex-direction: column;
gap: 16px;
`;

const _StudentBoxWrapper = styled.li`
width: 100%;
height: 70px;
background-color: ${({ theme }) => theme.color.gray1 || '#f5f5f5'};
box-shadow: 0 1px 20px rgba(204, 204, 204, 0.24);
border-radius: 8px;
padding: 17px 40px 17px 36px;
display: flex;
align-items: center;
justify-content: space-between;
`;

const _LeftSection = styled.div`
display: flex;
align-items: center;
gap: 16px;

> div:first-child {
margin-right: 8px;
}
`;

const _CenterSection = styled.div`
display: flex;
align-items: center;
gap: 12px;
margin-left: 24px;
flex: 1;
max-width: 45%;
`;

const _RightSection = styled.div`
display: flex;
align-items: center;
margin-left: auto;
`;
2 changes: 2 additions & 0 deletions services/admin/src/components/common/Skeleton/Home/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './StudentDetailSkeleton';
export * from './StudentListSkeleton';
Loading