Skip to content

Commit

Permalink
Merge pull request #53 from academic-relations/52-impl-student-fee-page
Browse files Browse the repository at this point in the history
impl student fee page
  • Loading branch information
wjeongchoi authored Nov 24, 2024
2 parents 2b8944f + 8c5a8a9 commit afc6c38
Show file tree
Hide file tree
Showing 11 changed files with 308 additions and 2 deletions.
14 changes: 14 additions & 0 deletions packages/web/public/temp/student-fee.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
85 changes: 85 additions & 0 deletions packages/web/src/app/my/student-fee/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"use client";

import React, { useState } from "react";

import Image from "next/image";

import FlexWrapper from "@sparcs-students/web/common/components/FlexWrapper";
import Typography from "@sparcs-students/web/common/components/Typography";
import StudentFeeChange from "@sparcs-students/web/features/studentFee/components/StudentFeeChange";
import StudentFeeStatus from "@sparcs-students/web/features/studentFee/components/StudentFeeStatus";

const mockSemesters = [
{
year: 2023,
semester: "봄",
},
{
year: 2023,
semester: "가을",
},
{
year: 2024,
semester: "봄",
},
{
year: 2024,
semester: "가을",
},
];

const mockChangeDate = new Date("2025-09-08");
const mockSemesterNow = {
year: 2024,
semester: "가을",
};

const StudentFee = () => {
const [payment, setPayment] = useState<boolean>(true);

return (
<FlexWrapper direction="column" gap={60}>
<Typography fs={30} lh={30} color="GREEN.800" fw="SEMIBOLD">
학생회비 납부 조회
</Typography>
<FlexWrapper direction="column" gap={32}>
<Typography fs={20} lh={20} fw="MEDIUM">
학생회비 납부 학기
</Typography>
<StudentFeeStatus semesters={mockSemesters} />
<Typography fs={16} lh={24} fw="REGULAR" color="GRAY.700">
2015년 가을까지 모든 재적학기는 회비를 납부한 것으로 인정되며, 현재
기록에 포함되어 있지 않습니다. <br />그 외 기록이 누락 된 경우
[email protected]로 문의해 주십시오. <br />
8회 학생회비를 납부 완료하신 학우분들은 별도의 공제 신청 없이 자동
공제가 적용됩니다. <br />
</Typography>
</FlexWrapper>
<FlexWrapper direction="column" gap={32}>
<Typography fs={20} lh={20} fw="MEDIUM">
학생회비 공제 / 미공제 변경
</Typography>
<StudentFeeChange
changeDate={mockChangeDate}
semesterNow={mockSemesterNow}
paymentStatus={payment}
finishPayment={mockSemesters.length >= 8}
setPayment={setPayment}
/>
</FlexWrapper>
<FlexWrapper direction="column" gap={32}>
<Typography fs={20} lh={20} fw="MEDIUM">
학생회비 관련 공지사항
</Typography>
{/* TODO: 임시 이미지 */}
<Image
src="/temp/student-fee.svg"
alt="student-fee notice"
width={840}
height={240}
/>
</FlexWrapper>
</FlexWrapper>
);
};
export default StudentFee;
22 changes: 22 additions & 0 deletions packages/web/src/common/components/FlexWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import isPropValid from "@emotion/is-prop-valid";
import styled from "styled-components";

interface FlexWrapperProps {
direction: "row" | "column";
gap: number;
justify?: string;
padding?: string;
}

const FlexWrapper = styled.div.withConfig({
shouldForwardProp: prop => isPropValid(prop),
})<FlexWrapperProps>`
display: flex;
position: relative;
flex-direction: ${({ direction }) => direction};
gap: ${({ gap }) => `${gap}px`};
justify-content: ${({ justify }) => justify ?? "flex-start"};
padding: ${({ padding }) => padding ?? 0};
`;

export default FlexWrapper;
7 changes: 5 additions & 2 deletions packages/web/src/common/components/Typography.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Theme } from "@sparcs-students/web/styles/themes";
import React from "react";

import styled from "styled-components";

import { Theme } from "@sparcs-students/web/styles/themes";

interface TypographyPropsBase extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
}
Expand Down Expand Up @@ -45,7 +47,8 @@ interface TypographyProps extends TypographyPropsBase {
const TypographyInner = styled.div<TypographyProps>`
color: ${({ color, theme }) =>
color ? getColorFromTheme(theme, color) : "inherit"};
font-family: ${({ theme, ff }) => (ff ? theme.fonts.FAMILY[ff] : "inherit")};
font-family: ${({ theme, ff }) =>
ff ? theme.fonts.FAMILY[ff] : theme.fonts.FAMILY.PRETENDARD};
font-size: ${({ fs }) => (fs ? `${fs}px` : "inherit")};
line-height: ${({ lh }) => (lh ? `${lh}px` : "inherit")};
font-weight: ${({ fw, theme }) => (fw ? theme.fonts.WEIGHT[fw] : "inherit")};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React from "react";
import Button from "@sparcs-students/web/common/components/Buttons/Button";
import FlexWrapper from "@sparcs-students/web/common/components/FlexWrapper";
import Typography from "@sparcs-students/web/common/components/Typography";
import { formatSimpleDate } from "@sparcs-students/web/utils/Date/formatDate";
import styled from "styled-components";
import { Semester } from "@sparcs-students/web/types/semester.type";

interface StudentFeeChangeProp {
changeDate: Date;
semesterNow: Semester;
paymentStatus: boolean;
finishPayment: boolean;
setPayment: (payment: boolean) => void;
}

const StudentFeeChangeWrapper = styled.div`
width: 840px; // TODO: 반응형
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 24px;
border-top: 1px solid ${({ theme }) => theme.colors.GRAY[400]};
border-bottom: 1px solid ${({ theme }) => theme.colors.GRAY[400]};
padding: 20px 12px;
align-items: center;
`;

const ButtonWrapper = styled.div`
width: 100px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
`;

const StudentFeeChange: React.FC<StudentFeeChangeProp> = ({
changeDate,
semesterNow,
paymentStatus,
finishPayment,
setPayment,
}) => {
const isChangeable = changeDate >= new Date();

return (
<StudentFeeChangeWrapper>
<FlexWrapper direction="row" gap={12}>
<Typography fw="MEDIUM" fs={20} lh={20}>
{semesterNow.year} {semesterNow.semester}학기
</Typography>
{isChangeable ? (
<Typography fs={14} lh={20} color="PRIMARY">
{formatSimpleDate(changeDate)}까지 변경 가능
</Typography>
) : (
<Typography fs={14} lh={20} color="RED.700">
변경 불가 기간
</Typography>
)}
</FlexWrapper>
{finishPayment ? (
<Typography fs={20} lh={20} color="BLUE.900" fw="SEMIBOLD">
학생회비 8회 납부 완료자
</Typography>
) : (
<Typography
fs={20}
lh={20}
color={paymentStatus ? "PRIMARY" : "RED.700"}
fw="SEMIBOLD"
>
학생회비 {paymentStatus ? "납부 (공제)" : "미납부 (미공제)"}{" "}
{isChangeable ? "예정" : ""}
</Typography>
)}
<ButtonWrapper>
{isChangeable && !finishPayment ? (
<Button onClick={() => setPayment(!paymentStatus)}>변경하기</Button>
) : (
<div />
)}
</ButtonWrapper>
</StudentFeeChangeWrapper>
);
};
export default StudentFeeChange;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from "react";
import styled from "styled-components";
import { Semester } from "@sparcs-students/web/types/semester.type";
import StudentFeePaid from "./_atomic/StudentFeePaid";
import StudentFeeNotPaid from "./_atomic/StudentFeeNotPaid";

interface StudentFeeStatusProp {
semesters: Semester[];
}

const StudentFeeStatusWrapper = styled.div`
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
// TODO: 반응형
gap: 24px;
`;

const StudentFeeStatus: React.FC<StudentFeeStatusProp> = ({ semesters }) => (
<StudentFeeStatusWrapper>
{semesters.map(semester => (
<StudentFeePaid
key={`${semester.year}-${semester.semester}`}
year={semester.year}
semester={semester.semester}
/>
))}
{Array.from({ length: 8 - semesters.length }).map(_ => (
<StudentFeeNotPaid />
))}
</StudentFeeStatusWrapper>
);

export default StudentFeeStatus;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react";

import Typography from "@sparcs-students/web/common/components/Typography";
import styled from "styled-components";

const StudentFeeNotPaidWrapper = styled.div`
width: 192px;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
background-color: ${({ theme }) => theme.colors.GRAY[400]};
border-radius: 20px;
`;

const StudentFeeNotPaid: React.FC = () => (
<StudentFeeNotPaidWrapper>
<Typography fw="MEDIUM" fs={18} lh={40} color="WHITE">
-
</Typography>
</StudentFeeNotPaidWrapper>
);
export default StudentFeeNotPaid;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react";

import Typography from "@sparcs-students/web/common/components/Typography";
import { Semester } from "@sparcs-students/web/types/semester.type";
import styled from "styled-components";

const StudentFeePaidWrapper = styled.div`
width: 192px;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
background-color: ${({ theme }) => theme.colors.GREEN[100]};
border-radius: 20px;
`;

const StudentFeePaid: React.FC<Semester> = ({ year, semester }) => (
<StudentFeePaidWrapper>
<Typography fw="MEDIUM" fs={18} lh={40}>
{year} {semester}학기
</Typography>
</StudentFeePaidWrapper>
);
export default StudentFeePaid;
4 changes: 4 additions & 0 deletions packages/web/src/styles/themes/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ const colors = {
200: "#F5A3A8",
700: "#B7202A",
},

BLUE: {
900: "#3A2682",
},
};

export default colors;
4 changes: 4 additions & 0 deletions packages/web/src/types/semester.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type Semester = {
year: number;
semester: string;
};
7 changes: 7 additions & 0 deletions packages/web/src/utils/Date/formatDate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { format } from "date-fns";
import { ko } from "date-fns/locale";

const formatSimpleDate = (date: Date) =>
format(date, "M월 d일", { locale: ko });

export { formatSimpleDate };

0 comments on commit afc6c38

Please sign in to comment.