Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file not shown.
Binary file not shown.
Binary file added public/fonts/nexon/NexonLv1GothicOTF-B.woff
Binary file not shown.
Binary file added public/fonts/nexon/NexonLv1GothicOTF-R.woff
Binary file not shown.
70 changes: 62 additions & 8 deletions src/app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,62 @@
"use client";
import Button from "@/app/components/button/default/Button";
import DotLoadingSpinner from "@/app/components/loading-spinner/DotLoadingSpinner";
import { useLogin } from "@/hooks/queries/auth/useLogin";
import { type LoginSchema, loginSchema } from "@/schemas/authSchema";
import { zodResolver } from "@hookform/resolvers/zod";
import Image from "next/image";
import Link from "next/link";
import { useForm } from "react-hook-form";
import { UserRole, userRoles } from "@/constants/userRoles";

export default function LoginPage() {
// 로그인 훅과 로딩 상태 관리
const { login, isPending } = useLogin();

// 폼 유효성 검사 및 상태 관리
const {
register,
handleSubmit,
formState: { errors },
setValue,
} = useForm<LoginSchema>({
resolver: zodResolver(loginSchema),
});

// 일반 로그인 제출 핸들러
const onSubmit = (data: LoginSchema) => {
login(data);
};

// 테스트 계정 로그인 핸들러 - 폼 유효성 검사 통과
const handleTestLogin = (role: UserRole) => {
const testCredentials = {
// 지원자 테스트 계정 정보
[userRoles.APPLICANT]: {
email: process.env.NEXT_PUBLIC_TEST_APPLICANT_ID as string,
password: process.env.NEXT_PUBLIC_TEST_APPLICANT_PASSWORD as string,
},
// 사장님 테스트 계정 정보
[userRoles.OWNER]: {
email: process.env.NEXT_PUBLIC_TEST_OWNER_ID as string,
password: process.env.NEXT_PUBLIC_TEST_OWNER_PASSWORD as string,
},
};

// setValue를 통해 폼 값을 직접 설정
const credentials = testCredentials[role];
setValue("email", credentials.email);
setValue("password", credentials.password);

// 설정된 값으로 폼 제출
handleSubmit((data) => login(data))();
};

return (
<div className="flex min-h-screen items-center justify-center bg-gradient-to-r from-lime-200 to-lime-300 px-4 py-12 sm:px-6 lg:px-8">
<div className="w-full max-w-md space-y-8 rounded-lg bg-white p-8 shadow-lg">
<div>
<h2 className="text-grayscale-900 text-center text-3xl font-bold tracking-tight">로그인</h2>
<div className="text-grayscale-900 text-center text-3xl font-bold tracking-tight">로그인</div>
<p className="text-grayscale-600 mt-2 text-center text-sm">
아직 계정이 없으신가요?{" "}
<Link href="/signup" className="font-medium text-lime-600 hover:text-lime-500">
Expand Down Expand Up @@ -55,14 +86,10 @@ export default function LoginPage() {
</div>
</div>

<div>
<button
type="submit"
disabled={isPending}
className="group relative flex w-full justify-center rounded-lg bg-lime-600 px-4 py-2 text-sm font-medium text-white hover:bg-lime-700 focus:outline-none focus:ring-2 focus:ring-lime-500 focus:ring-offset-2 disabled:bg-lime-300"
>
<div className="flex justify-center">
<Button type="submit" variant="solid" color="lime" width="md" disabled={isPending}>
{isPending ? <DotLoadingSpinner /> : "로그인"}
</button>
</Button>
</div>
<div className="flex items-center justify-center">
<hr className="flex-grow border-t border-grayscale-200" />
Expand All @@ -85,6 +112,33 @@ export default function LoginPage() {
<Image src="/icons/social/social_kakao.svg" width={72} height={72} alt="카카오 로그인" />
</Link>
</div>
<div className="flex items-center justify-center">
<hr className="flex-grow border-t border-grayscale-200" />
<span className="mx-4 text-sm text-grayscale-400">테스트 계정으로 로그인하기</span>
<hr className="flex-grow border-t border-grayscale-200" />
</div>
<div className="flex justify-center space-x-6">
<Button
type="button"
variant="outlined"
width="sm"
color="lime"
onClick={() => handleTestLogin(userRoles.APPLICANT)}
disabled={isPending}
>
지원자로 로그인
</Button>
<Button
type="button"
variant="solid"
width="sm"
color="lime"
onClick={() => handleTestLogin(userRoles.OWNER)}
disabled={isPending}
>
사장님으로 로그인
</Button>
</div>
</form>
</div>
</div>
Expand Down
13 changes: 5 additions & 8 deletions src/app/(auth)/signup/applicant/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Link from "next/link";
import { useForm } from "react-hook-form";
import Image from "next/image";
import DotLoadingSpinner from "@/app/components/loading-spinner/DotLoadingSpinner";
import Button from "@/app/components/button/default/Button";

export default function ApplicantSignupPage() {
const { signup, isPending } = useSignup();
Expand All @@ -32,7 +33,7 @@ export default function ApplicantSignupPage() {
<div className="flex min-h-screen items-center justify-center bg-gradient-to-r from-lime-200 to-lime-300 px-4 py-12 sm:px-6 lg:px-8">
<div className="w-full max-w-md space-y-8 rounded-lg bg-white p-8 shadow-lg">
<div>
<h2 className="text-grayscale-900 text-center text-3xl font-bold tracking-tight">지원자 회원가입</h2>
<div className="text-grayscale-900 text-center text-3xl font-bold tracking-tight">지원자 회원가입</div>
<p className="text-grayscale-600 mt-2 text-center text-sm">
이미 계정이 있으신가요?{" "}
<Link href="/login" className="font-medium text-lime-600 hover:text-lime-500">
Expand Down Expand Up @@ -98,14 +99,10 @@ export default function ApplicantSignupPage() {
{errors.phoneNumber && <p className="mt-1 text-sm text-red-600">{errors.phoneNumber.message}</p>}
</div>
</div>
<div>
<button
type="submit"
disabled={isPending}
className="group relative flex w-full justify-center rounded-lg bg-lime-600 px-4 py-2 text-sm font-medium text-white hover:bg-lime-700 focus:outline-none focus:ring-2 focus:ring-lime-500 focus:ring-offset-2 disabled:bg-lime-300"
>
<div className="flex justify-center">
<Button type="submit" variant="solid" color="lime" width="md" disabled={isPending}>
{isPending ? <DotLoadingSpinner /> : "회원가입"}
</button>
</Button>
</div>
<div className="flex items-center justify-center">
<hr className="flex-grow border-t border-grayscale-200" />
Expand Down
13 changes: 5 additions & 8 deletions src/app/(auth)/signup/owner/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Link from "next/link";
import { useForm } from "react-hook-form";
import Image from "next/image";
import DotLoadingSpinner from "@/app/components/loading-spinner/DotLoadingSpinner";
import Button from "@/app/components/button/default/Button";

export default function OwnerSignupPage() {
const { signup, isPending } = useSignup();
Expand All @@ -34,7 +35,7 @@ export default function OwnerSignupPage() {
<div className="flex min-h-screen items-center justify-center bg-gradient-to-r from-lime-200 to-lime-300 px-4 py-12 sm:px-6 lg:px-8">
<div className="w-full max-w-md space-y-8 rounded-lg bg-white p-8 shadow-lg">
<div>
<h2 className="text-grayscale-900 text-center text-3xl font-bold tracking-tight">사장님 회원가입</h2>
<div className="text-grayscale-900 text-center text-3xl font-bold tracking-tight">사장님 회원가입</div>
<p className="text-grayscale-600 mt-2 text-center text-sm">
이미 계정이 있으신가요?{" "}
<Link href="/login" className="font-medium text-lime-600 hover:text-lime-500">
Expand Down Expand Up @@ -120,14 +121,10 @@ export default function OwnerSignupPage() {
{errors.location && <p className="mt-1 text-sm text-red-600">{errors.location.message}</p>}
</div>
</div>
<div>
<button
type="submit"
disabled={isPending}
className="group relative flex w-full justify-center rounded-lg bg-lime-600 px-4 py-2 text-sm font-medium text-white hover:bg-lime-700 focus:outline-none focus:ring-2 focus:ring-lime-500 focus:ring-offset-2 disabled:bg-lime-300"
>
<div className="flex justify-center">
<Button type="submit" variant="solid" color="lime" width="md" disabled={isPending}>
{isPending ? <DotLoadingSpinner /> : "회원가입"}
</button>
</Button>
</div>
<div className="flex items-center justify-center">
<hr className="flex-grow border-t border-grayscale-200" />
Expand Down
30 changes: 20 additions & 10 deletions src/app/(home)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useEffect, useState, useRef } from "react";
import Link from "next/link";
import Image from "next/image";
import { useUser } from "@/hooks/queries/user/me/useUser";
import LinkBtn from "../components/button/default/LinkBtn";

export default function Home() {
const [visibleSections, setVisibleSections] = useState(new Set<string>());
Expand All @@ -16,16 +17,27 @@ export default function Home() {
observer.current = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const element = entry.target as HTMLElement;
const id = element.dataset.id ?? ""; // 기본값 설정
if (id) {
const element = entry.target as HTMLElement;
const id = element.dataset.id ?? "";
if (id) {
if (entry.isIntersecting) {
// 요소가 보일 때 애니메이션 적용
setVisibleSections((prev) => new Set(prev).add(id));
} else {
// 요소가 보이지 않을 때 애니메이션 제거
setVisibleSections((prev) => {
const newSet = new Set(prev);
newSet.delete(id);
return newSet;
});
}
}
});
},
{ threshold: 0.5 }
{
threshold: 0.2, // 임계값을 낮춰서 더 일찍 감지
rootMargin: "50px", // 여유 공간 추가
}
);

// 감시할 요소 선택 및 등록
Expand Down Expand Up @@ -59,11 +71,9 @@ export default function Home() {
한 곳에서 관리하는 알바 구인 플랫폼
</p>
{user ? (
<Link href="/alba-list">
<p className="font-nexon-regular text-black inline-block rounded-lg bg-green-500 px-4 py-2 text-sm sm:px-6 sm:py-3 sm:text-base md:px-8 md:py-4 md:text-lg lg:px-10 lg:py-5 lg:text-xl">
알바 둘러보기
</p>
</Link>
<LinkBtn href="/alba-list" variant="solid" width="lg" fontSize="lg" color="lime" disabled={false}>
알바 둘러보기
</LinkBtn>
) : (
<Link href="/login">
<p className="font-nexon-regular text-black inline-block rounded-lg bg-green-500 px-4 py-2 text-sm sm:px-6 sm:py-3 sm:text-base md:px-8 md:py-4 md:text-lg lg:px-10 lg:py-5 lg:text-xl">
Expand Down
6 changes: 3 additions & 3 deletions src/app/(pages)/mypage/components/FilterBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ export default function FilterBar() {
<div className="w-full bg-white">
{/* 마이페이지 섹션 */}
<div className="flex items-center justify-between">
<h1 className="text-grayscale-900 py-4 text-xl font-bold sm:py-6 sm:text-2xl">마이페이지</h1>
<div className="text-grayscale-900 py-4 text-xl font-bold sm:py-6 sm:text-2xl">마이페이지</div>
{/* sm, md에서는 케밥 메뉴, lg 이상에서는 버튼 */}
<div>
<div className="hidden lg:flex lg:gap-2">
<Button variant="solid" width="sm" onClick={handleEditProfile}>
<Button variant="outlined" color="lime" width="sm" onClick={handleEditProfile}>
내 정보 수정
</Button>
<Button variant="outlined" width="sm" onClick={handleChangePassword}>
<Button variant="solid" color="lime" width="sm" onClick={handleChangePassword}>
비밀번호 변경
</Button>
</div>
Expand Down
11 changes: 0 additions & 11 deletions src/app/(pages)/mypage/components/sections/PostsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,6 @@ export default function PostsSection() {

return (
<div className="flex min-h-screen flex-col items-center">
{/* 정렬 옵션 섹션 */}
<div className="fixed left-0 right-0 top-16 z-30 bg-white shadow-sm">
<div className="w-full border-b border-line-100">
<div className="mx-auto flex max-w-screen-xl items-center justify-end gap-2 px-4 py-4 md:px-6 lg:px-8">
<div className="flex items-center gap-4">
<SortSection pathname={pathname} searchParams={searchParams} />
</div>
</div>
</div>
</div>

{/* 메인 콘텐츠 영역 */}
<div className="w-full">
{!data?.pages?.[0]?.data?.length ? (
Expand Down
8 changes: 7 additions & 1 deletion src/app/components/button/default/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: "solid" | "outlined";
width?: "xs" | "sm" | "md" | "lg";
radius?: "lg" | "full";
color?: "orange" | "gray";
color?: "orange" | "gray" | "lime";
icon?: ReactNode;
}
/**
Expand Down Expand Up @@ -47,6 +47,12 @@ const Button = ({
outlined:
"border-2 border-grayscale-200 text-grayscale-900 hover:border-grayscale-300 hover:bg-grayscale-50 focus:ring-1 focus:ring-grayscale-200 focus:outline-none disabled:border-grayscale-100 disabled:text-grayscale-100 disabled:cursor-not-allowed disabled:hover:bg-transparent",
},
lime: {
solid:
"bg-lime-600 text-white hover:bg-lime-700 focus:ring-1 focus:ring-lime-500 focus:outline-none disabled:bg-lime-300 disabled:cursor-not-allowed",
outlined:
"border-2 border-lime-600 text-lime-600 hover:border-lime-700 hover:text-lime-700 focus:ring-1 focus:ring-lime-500 focus:outline-none disabled:border-lime-300 disabled:text-lime-300 disabled:cursor-not-allowed disabled:hover:bg-transparent",
},
};

const widths = {
Expand Down
Loading
Loading