Skip to content

Commit

Permalink
Merge branch 'main' into feat/#120/mainpage
Browse files Browse the repository at this point in the history
  • Loading branch information
JeongWuk authored Nov 13, 2023
2 parents 1297e6e + e2ff81e commit 5d77c9e
Show file tree
Hide file tree
Showing 20 changed files with 539 additions and 105 deletions.
32 changes: 26 additions & 6 deletions src/app/(steady)/steady/applicant/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { usePathname } from "next/navigation";
import SteadyLogo from "@/images/turtle.png";
import { Separator } from "@radix-ui/themes";
import { useQuery } from "@tanstack/react-query";
import changeApplicationStatus from "@/services/application/changeApplicationStatus";
import getApplicationsList from "@/services/application/getApplicationsList";
import Button, { buttonSize } from "@/components/_common/Button";
import { AlertModal } from "@/components/_common/Modal";
Expand All @@ -15,12 +16,11 @@ const selectedEffectStyle = "bg-st-skyblue-50 text-st-primary";
const normalEffectStyle = "hover:bg-st-gray-50";

const ApplicantLayout = ({ children }: { children: ReactNode }) => {
const pathname = usePathname();
const steadyId = pathname.split("/").at(-1);
const id = usePathname().split("/").pop();
const [selectedItem, setSelectedItem] = useState(0);
const { data: applicationsListData } = useQuery({
queryKey: ["applicationsList"],
queryFn: () => getApplicationsList(steadyId as string),
queryFn: () => getApplicationsList(id as string), // 스테디 id
});

return (
Expand Down Expand Up @@ -49,7 +49,10 @@ const ApplicantLayout = ({ children }: { children: ReactNode }) => {
height={50}
className="rounded-full border-1"
/>
<Link href={`/steady/applicant/${user.id}`}>
<Link
href={`/steady/applicant/${user.id}`}
className="w-full"
>
<div>{user.nickname}</div>
</Link>
</div>
Expand All @@ -60,6 +63,7 @@ const ApplicantLayout = ({ children }: { children: ReactNode }) => {
{children}
</div>
<Separator className="h-5 w-auto bg-st-gray-400" />

<div className="flex justify-end gap-10">
<AlertModal
trigger={
Expand All @@ -68,7 +72,15 @@ const ApplicantLayout = ({ children }: { children: ReactNode }) => {
</Button>
}
actionButton={
<Button className={`${buttonSize.sm} bg-st-red text-st-white`}>
<Button
className={`${buttonSize.sm} bg-st-red text-st-white`}
onClick={() =>
id &&
changeApplicationStatus(id, {
status: "REJECTED",
})
}
>
거절
</Button>
}
Expand All @@ -82,7 +94,15 @@ const ApplicantLayout = ({ children }: { children: ReactNode }) => {
</Button>
}
actionButton={
<Button className={`${buttonSize.sm} bg-st-green text-st-white`}>
<Button
className={`${buttonSize.sm} bg-st-green text-st-white`}
onClick={() =>
id &&
changeApplicationStatus(id, {
status: "ACCEPTED",
})
}
>
승인
</Button>
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/_common/Icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,8 @@ const Icon = ({ name, size, color }: IconProps) => {
<path
d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
fill="currentColor"
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
></path>
</svg>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import { Fragment } from "react";
import useLoginStepsStore from "@/stores/loginSteps";
import {
SetInterestsAndStacks,
SetNickname,
SetPositionAndStacks,
SocialLoginEnd,
SocialLoginStart,
SteadyDescriptionEnd,
Expand All @@ -21,7 +21,7 @@ const LoginStepsContainer = () => {
case 1:
return <SetNickname />;
case 2:
return <SetInterestsAndStacks />;
return <SetPositionAndStacks />;
case 3:
return <SteadyDescriptionStart />;
case 4:
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,119 @@
import Input from "@/components/_common/Input";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { useToast } from "@/components/ui/use-toast";
import type { NicknameSchemaType } from "@/schemas/setNickname";
import { nicknameSchema } from "@/schemas/setNickname";
import useLoginStepsStore from "@/stores/loginSteps";
import useNewUserInfoStore from "@/stores/newUserInfo";
import { zodResolver } from "@hookform/resolvers/zod";
import checkSameNickname from "@/services/user/checkSameNickname";
import Button, { buttonSize } from "@/components/_common/Button";
import Icon from "@/components/_common/Icon";

export const loginTextStyles = "text-26 font-bold max-mobile:text-20";

const SetNickname = () => {
const { nickname, setNickname } = useNewUserInfoStore();
const { setIncreaseSteps } = useLoginStepsStore();
const {
register,
setValue,
handleSubmit,
watch,
trigger,
formState: { errors },
} = useForm<NicknameSchemaType>({
mode: "onChange",
resolver: zodResolver(nicknameSchema),
});
const { toast } = useToast();
const [activeNextBtn, setActiveNextBtn] = useState(false);

useEffect(() => {
setValue("nickname", nickname);
}, [nickname, setValue]);

const handleCheckSameNickname = async () => {
const watchNickname = watch("nickname");
const isValid = await trigger("nickname");
if (!isValid) {
setActiveNextBtn(false);
return;
}
const { exist } = await checkSameNickname(watchNickname);
if (exist) {
setActiveNextBtn(false);
toast({
description: "이미 사용중인 닉네임입니다!",
variant: "red",
});
} else {
setNickname(watchNickname);
toast({
description: "사용 가능한 닉네임입니다!",
variant: "green",
});
setActiveNextBtn(true);
}
};

return (
<div className="flex h-full w-full flex-col items-center justify-evenly">
<div className="flex flex-col items-center justify-evenly gap-10">
<div className="flex h-full flex-col items-center justify-center gap-10">
<div className={loginTextStyles}>
<span className="text-st-primary">스테디</span>에 오신 걸 환영합니다!
</div>
<div className={loginTextStyles}>닉네임을 설정해주세요</div>
</div>
{/* TODO: data 받기, react-hook-form or zod 사용, 유효성 검사 */}
<Input inputName="name-input" />
<form
onSubmit={handleSubmit(handleCheckSameNickname)}
className="flex h-full flex-col items-center justify-between"
>
<div className="flex flex-col gap-10">
<div className="flex items-center justify-center gap-10">
<input
className="max-mobile:w-full h-55 w-400 items-center rounded-12 border-2 border-solid border-st-gray-100 pl-5 pr-5 text-center text-lg outline-none"
type="text"
{...register("nickname")}
onChange={(event) => {
setValue("nickname", event.target.value);
}}
placeholder="닉네임을 입력해주세요."
/>
<button
type="submit"
onClick={handleCheckSameNickname}
>
{activeNextBtn ? (
<Icon
name="check"
size={30}
color="text-st-green"
/>
) : (
<Icon
name="check"
size={30}
color=""
/>
)}
</button>
</div>
{errors.nickname?.message && (
<div className="text-st-red">{errors.nickname?.message}</div>
)}
</div>
<Button
className={`${buttonSize.md} text-st-white ${
activeNextBtn ? "bg-st-primary" : "bg-st-gray-100"
}`}
type="button"
onClick={() => setIncreaseSteps()}
disabled={!activeNextBtn}
>
다음
</Button>
</form>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { useForm } from "react-hook-form";
import { Form, FormField, FormItem, FormMessage } from "@/components/ui/form";
import {
type PositionAndStacksSchemaType,
positionAndStacksSchema,
} from "@/schemas/setNickname";
import useLoginStepsStore from "@/stores/loginSteps";
import useNewUserInfoStore from "@/stores/newUserInfo";
import { zodResolver } from "@hookform/resolvers/zod";
import Button, { buttonSize } from "@/components/_common/Button";
import { MultiSelector, SingleSelector } from "@/components/_common/Selector";
import { extractValue } from "@/utils/extractValue";
import { loginTextStyles } from "./SetNickname";

const dummyPositions = [
{ value: "1", label: "프론트엔드" },
{ value: "2", label: "백엔드" },
{ value: "3", label: "디자인" },
{ value: "4", label: "기획" },
{ value: "5", label: "마케팅" },
{ value: "6", label: "기타" },
];

const dummyStacks = [
{ value: "1", label: "React" },
{ value: "2", label: "Next.js" },
{ value: "3", label: "Vue" },
{ value: "4", label: "Nuxt.js" },
{ value: "5", label: "Angular" },
{ value: "6", label: "Svelte" },
{ value: "7", label: "Express" },
{ value: "8", label: "Nest.js" },
{ value: "9", label: "Django" },
{ value: "10", label: "Flask" },
{ value: "11", label: "Spring" },
{ value: "12", label: "MyBatis" },
{ value: "13", label: "JPA" },
{ value: "14", label: "Hibernate" },
{ value: "15", label: "MySQL" },
{ value: "16", label: "MariaDB" },
];

const SetPositionAndStacks = () => {
const { setIncreaseSteps } = useLoginStepsStore();
const { nickname, positionId, stackIds, setPositionId, setStackIds } =
useNewUserInfoStore();
const userInfos = useForm<PositionAndStacksSchemaType>({
values: { position: positionId, stacks: stackIds },
resolver: zodResolver(positionAndStacksSchema),
});

const savePositionAndStacks = (data: PositionAndStacksSchemaType) => {
setPositionId(data.position);
setStackIds(data.stacks);
setIncreaseSteps();
};

return (
<div className="flex h-full w-full flex-col items-center justify-evenly px-10">
<div className="flex h-full flex-col items-center justify-center gap-10 text-center">
<div className={loginTextStyles}>
<div className="mb-20">멋진 닉네임 이네요!</div>
<div>
<div>{`"${nickname}"님의 `}</div>
<span className="text-st-primary">포지션</span>
<span></span>
<span className="text-st-primary"> 기술 스택</span>을 알려주세요!
</div>
</div>
</div>
<Form {...userInfos}>
<form
onSubmit={userInfos.handleSubmit(savePositionAndStacks)}
className="flex h-full w-full flex-col items-center px-30"
>
<div className="flex h-full w-full flex-col gap-20 text-center">
<FormField
control={userInfos.control}
name={"position"}
render={() => (
<FormItem className="flex flex-col gap-10">
<SingleSelector
initialLabel={
dummyPositions.find(
(position) => position.value === String(positionId),
)?.label ?? "포지션"
}
items={dummyPositions}
onSelectedChange={(selected) => {
setPositionId(Number(selected));
}}
/>
<FormMessage />
</FormItem>
)}
/>
<div className="h-130 overflow-auto scrollbar-hide">
<FormField
control={userInfos.control}
name={"stacks"}
render={() => (
<FormItem className="flex flex-col gap-10">
<MultiSelector
initialLabel={
stackIds.length
? dummyStacks
.filter((item) =>
stackIds.includes(Number(item.value)),
)
.map((item) => item.label)
.join(", ")
: "기술 스택"
}
items={dummyStacks}
onSelectedChange={(selected) => {
const stackIds = extractValue(selected).map(Number);
setStackIds(stackIds);
}}
/>
<FormMessage />
</FormItem>
)}
/>
</div>
</div>
<Button
className={`${buttonSize.md} h-[50px] bg-st-primary text-st-white`}
type="submit"
>
다음
</Button>
</form>
</Form>
</div>
);
};

export default SetPositionAndStacks;
Loading

0 comments on commit 5d77c9e

Please sign in to comment.