Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate /common-space to react-hook-form #1202

Merged
merged 12 commits into from
Nov 26, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ import apiCms006 from "@sparcs-clubs/interface/api/common-space/endpoint/apiCms0
import apiCms007 from "@sparcs-clubs/interface/api/common-space/endpoint/apiCms007";

import { ZodPipe } from "@sparcs-clubs/api/common/pipe/zod-pipe";
import { Public } from "@sparcs-clubs/api/common/util/decorators/method-decorator";
import {
Public,
Student,
} from "@sparcs-clubs/api/common/util/decorators/method-decorator";

import { GetStudent } from "@sparcs-clubs/api/common/util/decorators/param-decorator";

import { CommonSpaceService } from "../service/common-space.service";

Expand Down Expand Up @@ -75,68 +80,71 @@ export class CommonSpaceController {
return result;
}

@Student()
@Post("student/common-spaces/common-space/:spaceId/orders/order")
@UsePipes(new ZodPipe(apiCms003))
async postStudentCommonSpaceUsageOrder(
@GetStudent() user: GetStudent,
@Param() param: ApiCms003RequestParam,
@Body() body: ApiCms003RequestBody,
): Promise<ApiCms003ResponseCreated> {
const studentId = 1;
const result =
await this.commonspaceService.postStudentCommonSpaceUsageOrder(
param.spaceId,
body.clubId,
studentId,
user.studentId,
body.startTerm,
body.endTerm,
);
return result;
}

@Student()
@Delete("student/common-spaces/common-space/:spaceId/orders/order/:orderId")
@UsePipes(new ZodPipe(apiCms004))
async deleteStudentCommonSpaceUsageOrder(
@GetStudent() user: GetStudent,
@Param() param: ApiCms004RequestParam,
): Promise<ApiCms004ResponseOK> {
const studentId = 1;
const result =
await this.commonspaceService.deleteStudentCommonSpaceUsageOrder(
param.spaceId,
param.orderId,
studentId,
user.studentId,
);
return result;
}

@Student()
@Post("executive/common-spaces/common-space/:spaceId/orders")
@UsePipes(new ZodPipe(apiCms005))
async postExecutiveCommonSpaecUsageOrder(
@GetStudent() user: GetStudent,
@Param() param: ApiCms005RequestParam,
@Body() body: ApiCms005RequestBody,
): Promise<ApiCms005ResponseCreated> {
const studentId = 1;

// 정기신청의 경우 사전에 미리 예약된 내역이 없고, 신청 과정에서 사용 가능한 시간에 대한 확인이 필요없다고 가정함.
const result =
await this.commonspaceService.postExecutiveCommonSpaecUsageOrder(
param.spaceId,
body.clubId,
studentId,
user.studentId,
body.startTime,
body.endTime,
);
return result;
}

@Student()
@Get("student/common-spaces/orders")
@UsePipes(new ZodPipe(apiCms006))
async getStudentCommonSpacesUsageOrder(
@GetStudent() user: GetStudent,
@Query() query: ApiCms006RequestQuery,
): Promise<ApiCms006ResponseOk> {
const studentId = 1;
const result =
await this.commonspaceService.getStudentCommonSpacesUsageOrder(
studentId,
user.studentId,
query.clubId,
query.startDate,
query.endDate,
Expand All @@ -146,15 +154,16 @@ export class CommonSpaceController {
return result;
}

@Student()
@Get("student/common-spaces/orders/my")
@UsePipes(new ZodPipe(apiCms007))
async getStudentCommonSpacesUsageOrderMy(
@GetStudent() user: GetStudent,
@Query() query: ApiCms007RequestQuery,
): Promise<ApiCms007ResponseOk> {
const studentId = 1;
const result =
await this.commonspaceService.getStudentCommonSpacesUsageOrderMy(
studentId,
user.studentId,
query.startDate,
query.endDate,
query.pageOffset,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,65 +1,117 @@
import React, { useEffect, useState } from "react";
import React, { useEffect } from "react";

import { useFormContext } from "react-hook-form";

import AsyncBoundary from "@sparcs-clubs/web/common/components/AsyncBoundary";

import Button from "@sparcs-clubs/web/common/components/Button";
import Card from "@sparcs-clubs/web/common/components/Card";
import FormController from "@sparcs-clubs/web/common/components/FormController";
import PhoneInput from "@sparcs-clubs/web/common/components/Forms/PhoneInput";

import TextInput from "@sparcs-clubs/web/common/components/Forms/TextInput";
import Select from "@sparcs-clubs/web/common/components/Select";
import StyledBottom from "@sparcs-clubs/web/common/components/StyledBottom";

import useGetUserProfile from "@sparcs-clubs/web/common/services/getUserProfile";
import { CommonSpaceInfoProps } from "@sparcs-clubs/web/features/common-space/types/commonSpace";
import { CommonSpaceInterface } from "@sparcs-clubs/web/features/common-space/types/commonSpace";

const CommonSpaceInfoFirstFrame: React.FC<
CommonSpaceInfoProps & { setNextEnabled: (enabled: boolean) => void }
> = ({ setNextEnabled, body, setBody }) => {
const { data, isLoading, isError } = useGetUserProfile();
interface CommonSpaceInfoFirstFrameProps {
onPrev: VoidFunction;
onNext: VoidFunction;
}

const [hasSelectError, setHasSelectError] = useState(false);
const CommonSpaceInfoFirstFrame: React.FC<CommonSpaceInfoFirstFrameProps> = ({
onPrev,
onNext,
}) => {
const {
control,
reset,
setValue,
formState: { isValid, isDirty },
} = useFormContext<CommonSpaceInterface>();

useEffect(() => {
setBody({ ...body, email: data?.email });
}, [data]);
const { data, isLoading, isError } = useGetUserProfile();

useEffect(() => {
const allConditionsMet =
Boolean(body.clubId) && Boolean(body.email) && !hasSelectError;
setNextEnabled(allConditionsMet);
}, [body, hasSelectError]);

const [phoneNumber, setPhoneNumber] = useState(data?.phoneNumber || "");
if (data) {
reset({
agreement: true,
clubName: data.clubs[0]?.name_kr || "",
name: data.name || "",
phoneNumber: data.phoneNumber || "",
});
}
}, [data, reset]);

return (
<Card outline gap={40}>
<AsyncBoundary isLoading={isLoading} isError={isError}>
<Select
items={
data?.clubs.map(club => ({
label: club.name_kr,
value: club.id.toString(),
selectable: true,
})) || []
}
value={body.clubId?.toString()}
onChange={value => setBody({ ...body, clubId: Number(value) })}
label="동아리 이름"
setErrorStatus={setHasSelectError}
<AsyncBoundary isLoading={isLoading || !data} isError={isError}>
<Card outline gap={40}>
<FormController
name="clubName"
control={control}
required
defaultValue={data?.clubs[0].name_kr || ""}
renderItem={({ onChange, value }) => (
<Select
onChange={selectedValue => {
setValue("body.clubId", parseInt(selectedValue));
onChange(selectedValue);
}}
items={
data?.clubs.map(club => ({
label: club.name_kr,
value: club.id.toString(),
selectable: true,
})) || []
}
label="동아리 이름"
value={value}
/>
)}
/>
<TextInput
label="신청자 이름"
placeholder={data?.name || ""}
disabled
<FormController
name="name"
control={control}
required
renderItem={() => (
<TextInput
label="신청자 이름"
placeholder={data?.name || ""}
disabled
/>
)}
/>
<PhoneInput
label="신청자 전화번호"
value={phoneNumber}
placeholder={data?.phoneNumber || ""}
onChange={setPhoneNumber}
disabled
<FormController
name="phoneNumber"
control={control}
minLength={13}
required
defaultValue={data?.phoneNumber || ""}
renderItem={({ onChange, value }) => (
<PhoneInput
label="신청자 전화번호"
placeholder={data?.phoneNumber || ""}
onChange={val => {
setValue("phoneNumber", val);
onChange(val);
}}
value={value}
/>
)}
/>
</AsyncBoundary>
</Card>
</Card>
<StyledBottom>
<Button onClick={onPrev}>이전</Button>
<Button
onClick={onNext}
type={isValid && isDirty ? "default" : "disabled"}
>
다음
</Button>
</StyledBottom>
</AsyncBoundary>
);
};

Expand Down
Loading