Skip to content

Commit 405f554

Browse files
committed
Merge branch 'dev' of https://github.com/FE9-2/workroot into feat/oauth
2 parents 6d37c6e + 34c1f7b commit 405f554

File tree

14 files changed

+82
-121
lines changed

14 files changed

+82
-121
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: workRoot CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main # main ๋ธŒ๋žœ์น˜์— ํ‘ธ์‹œ๋  ๋•Œ ์‹คํ–‰
7+
- dev
8+
pull_request:
9+
branches:
10+
- dev
11+
12+
jobs:
13+
lint-and-build:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v3
19+
20+
- name: Set up Node.js
21+
uses: actions/setup-node@v3
22+
with:
23+
node-version: "20" # ์ตœ์‹  Node.js 20.x.x ๋ฒ„์ „ ์‚ฌ์šฉ
24+
25+
- name: Cache dependencies
26+
uses: actions/cache@v3
27+
with:
28+
path: ~/.npm
29+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
30+
restore-keys: |
31+
${{ runner.os }}-node-
32+
33+
- name: Install dependencies
34+
run: npm install
35+
36+
- name: Run linter
37+
run: npm run lint
38+
39+
- name: Build project
40+
run: npm run build

โ€Žsrc/app/(pages)/(addform)/addform/sections/WorkCondition.tsxโ€Ž

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,17 @@ export default function WorkCondition({ formData, onUpdate }: WorkConditionProps
5656
if (start) setValue("workStartDate", start.toISOString());
5757
if (end) setValue("workEndDate", end.toISOString());
5858
};
59+
5960
const errorTextStyle =
6061
"absolute -bottom-[26px] right-1 text-[13px] text-sm font-medium leading-[22px] text-state-error lg:text-base lg:leading-[26px]";
6162

6263
return (
6364
<div className="relative">
6465
<FormProvider {...methods}>
6566
<form onSubmit={handleSubmit(onSubmit)} className="my-8 flex flex-col gap-4">
67+
{/* ์ง€๋„ API ์—ฐ๋™ */}
6668
<Label>๊ทผ๋ฌด ์œ„์น˜</Label>
67-
<LocationInput variant="white" />
69+
<LocationInput variant="white" {...register("location", { required: "๊ทผ๋ฌด ์œ„์น˜๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”." })} />
6870

6971
<div className="relative flex flex-col gap-2">
7072
<Label>๊ทผ๋ฌด ๊ธฐ๊ฐ„</Label>
@@ -94,7 +96,12 @@ export default function WorkCondition({ formData, onUpdate }: WorkConditionProps
9496
</div>
9597

9698
<Label>์‹œ๊ธ‰</Label>
97-
<BaseInput variant="white" afterString="์›" type="number" />
99+
<BaseInput
100+
{...register("hourlyWage", { required: "์‹œ๊ธ‰์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”." })}
101+
variant="white"
102+
afterString="์›"
103+
errormessage={errors.hourlyWage?.message}
104+
/>
98105

99106
<Label>๊ณต๊ฐœ ์„ค์ •</Label>
100107
<div className="flex px-[14px]">

โ€Žsrc/app/api/users/me/route.tsโ€Ž

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export async function GET() {
1010
const accessToken = cookies().get("accessToken")?.value;
1111

1212
if (!accessToken) {
13-
return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
13+
return new Response(null, { status: 200 });
1414
}
1515

1616
// ๋‚ด ์ •๋ณด ์กฐํšŒ ์š”์ฒญ
@@ -23,7 +23,9 @@ export async function GET() {
2323
return NextResponse.json(response.data);
2424
} catch (error: unknown) {
2525
if (error instanceof AxiosError) {
26-
console.error("GET /api/users/me error:", error);
26+
if (error.response?.status === 401) {
27+
return new Response(null, { status: 200 });
28+
}
2729
if (error.response) {
2830
return NextResponse.json({ message: error.response.data.message }, { status: error.response.status });
2931
}
@@ -42,7 +44,6 @@ export async function PATCH(request: Request) {
4244
}
4345

4446
const body = await request.json();
45-
console.log("PATCH /users/me request body:", body);
4647

4748
const response = await apiClient.patch("/users/me", body, {
4849
headers: {
@@ -51,11 +52,6 @@ export async function PATCH(request: Request) {
5152
},
5253
});
5354

54-
console.log("PATCH /users/me response:", {
55-
status: response.status,
56-
data: response.data,
57-
});
58-
5955
if (response.status === 200 && response.data) {
6056
return NextResponse.json(response.data);
6157
}

โ€Žsrc/app/components/button/default/CheckBtn.tsxโ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ interface CheckBtnProps extends InputHTMLAttributes<HTMLInputElement> {
66
label: string; // ์ฒดํฌ๋ฐ•์Šค์˜ ๋ ˆ์ด๋ธ”
77
name: string; // ์ฒดํฌ๋ฐ•์Šค์˜ name ์†์„ฑ
88
value: string; // ์ฒดํฌ๋ฐ•์Šค์˜ value ์†์„ฑ
9+
checked?: boolean; // ์ฒดํฌ๋ฐ•์Šค๊ฐ€ ์„ ํƒ๋œ ์ƒํƒœ์ธ์ง€ ์—ฌ๋ถ€
910
disabled?: boolean; // ์ฒดํฌ๋ฐ•์Šค๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋œ ์ƒํƒœ์ธ์ง€ ์—ฌ๋ถ€
1011
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
1112
}

โ€Žsrc/app/components/input/file/ImageInput/ImageInputwithPlaceHolder.tsxโ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ const ImageInputwithPlaceHolder = () => {
4343
name="image"
4444
onFileAction={handleFileChange}
4545
size={size}
46-
isImage={true}
4746
placeholder=""
4847
/>
4948
<div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center">

โ€Žsrc/app/components/input/text/LocationInput.tsxโ€Ž

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,24 @@
33
import { IoLocationSharp } from "react-icons/io5";
44
import BaseInput from "./BaseInput";
55
import { BaseInputProps } from "@/types/textInput";
6+
import { forwardRef } from "react";
67

7-
const LocationInput = ({ type = "text", variant, errormessage, feedbackMessage, ...props }: BaseInputProps) => {
8-
return (
9-
<BaseInput
10-
type={type}
11-
variant={variant || "white"}
12-
beforeIcon={<IoLocationSharp className="size-6 text-grayscale-100 lg:size-8" />}
13-
placeholder="์œ„์น˜๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."
14-
errormessage={errormessage}
15-
feedbackMessage={feedbackMessage}
16-
{...props}
17-
/>
18-
);
19-
};
8+
const LocationInput = forwardRef<HTMLInputElement, BaseInputProps>(
9+
({ type = "text", variant, errormessage, feedbackMessage, ...props }, ref) => {
10+
return (
11+
<BaseInput
12+
type={type}
13+
variant={variant || "white"}
14+
beforeIcon={<IoLocationSharp className="size-6 text-grayscale-100 lg:size-8" />}
15+
placeholder="์œ„์น˜๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."
16+
errormessage={errormessage}
17+
feedbackMessage={feedbackMessage}
18+
{...props}
19+
/>
20+
);
21+
}
22+
);
23+
24+
LocationInput.displayName = "LocationInput";
2025

2126
export default LocationInput;

โ€Žsrc/app/components/layout/Header.tsxโ€Ž

Lines changed: 4 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,79 +5,21 @@ import Link from "next/link";
55
import { usePathname, useRouter } from "next/navigation";
66
import { cn } from "@/lib/tailwindUtil";
77
import { useAuth } from "@/hooks/useAuth";
8-
import { useState, useEffect } from "react";
9-
import axios from "axios";
10-
import { UserResponse } from "@/types/response/user";
11-
import { useQueryClient } from "@tanstack/react-query";
8+
import { useState } from "react";
129
import { toast } from "react-hot-toast";
10+
import { useUser } from "@/hooks/useUser";
1311

1412
export default function Header() {
15-
const [user, setUser] = useState<UserResponse | null>(null);
1613
const { logout } = useAuth();
14+
const { user, isLoading } = useUser();
1715
const pathname = usePathname();
1816
const router = useRouter();
19-
const queryClient = useQueryClient();
2017
const [isSideMenuOpen, setIsSideMenuOpen] = useState(false);
21-
const [isInitialized, setIsInitialized] = useState(false);
2218

2319
// ์ธ์ฆ์ด ํ•„์š”์—†๋Š” ๊ณต๊ฐœ ๊ฒฝ๋กœ๋“ค
24-
const publicPaths = ["/", "/albaList", "/albaTalk", "/login", "/signup", "/signup/applicant", "/signup/owner"];
25-
26-
// ์ƒˆ๋กœ๊ณ ์นจ ์‹œ ํ† ํฐ ๊ฐฑ์‹  ๋ฐ ์œ ์ € ์ •๋ณด ๋กœ๋“œ
27-
useEffect(() => {
28-
const initializeAuth = async () => {
29-
try {
30-
const storedUser = localStorage.getItem("user");
31-
const userData: UserResponse | null = storedUser ? JSON.parse(storedUser) : null;
32-
setUser(userData);
33-
34-
if (userData) {
35-
await axios.post("/api/auth/refresh");
36-
queryClient.setQueryData(["user"], { user: userData });
37-
}
38-
} catch (error) {
39-
console.error("Auth initialization failed:", error);
40-
localStorage.removeItem("user");
41-
setUser(null);
42-
queryClient.setQueryData(["user"], { user: null });
43-
if (!publicPaths.includes(pathname)) {
44-
router.push("/login");
45-
}
46-
} finally {
47-
setIsInitialized(true);
48-
}
49-
};
50-
51-
initializeAuth();
52-
}, [pathname, queryClient, router]);
53-
54-
// React Query ์บ์‹œ ๋ณ€๊ฒฝ ๊ฐ์ง€
55-
useEffect(() => {
56-
// ์บ์‹œ ๊ตฌ๋… ์„ค์ •
57-
const unsubscribe = queryClient.getQueryCache().subscribe(() => {
58-
const userData = queryClient.getQueryData<{ user: UserResponse | null }>(["user"]);
59-
if (userData) {
60-
setUser(userData.user);
61-
}
62-
});
63-
64-
// ์ดˆ๊ธฐ ์ƒํƒœ ์„ค์ •
65-
const userData = queryClient.getQueryData<{ user: UserResponse | null }>(["user"]);
66-
if (userData) {
67-
setUser(userData.user);
68-
}
69-
70-
// ํด๋ฆฐ์—… ํ•จ์ˆ˜
71-
return () => {
72-
unsubscribe();
73-
};
74-
}, [queryClient]);
75-
7620
const handleLogout = async () => {
7721
logout();
7822
toast.success("๋กœ๊ทธ์•„์›ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!");
79-
setUser(null);
80-
queryClient.setQueryData(["user"], { user: null });
8123
setIsSideMenuOpen(false);
8224
router.push("/login");
8325
};
@@ -93,7 +35,7 @@ export default function Header() {
9335
};
9436

9537
// ๋กœ๋”ฉ ์‹œ๊ฐ„์ด 1์ดˆ ์ด์ƒ์ผ ๋•Œ๋งŒ ์Šค์ผˆ๋ ˆํ†ค UI ํ‘œ์‹œ
96-
if (!isInitialized) {
38+
if (isLoading) {
9739
return (
9840
<header className="fixed left-0 right-0 top-0 z-50 bg-lime-100 -tracking-widest md:tracking-normal">
9941
<div className="container mx-auto px-4">

โ€Žsrc/app/components/modal/modals/form/EditMyProfileModal.tsxโ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ const EditMyProfileModal = ({ isOpen, onClose, className }: EditMyProfileModalPr
110110
const updateResponse = await axios.patch("/api/users/me", updateData);
111111

112112
if (updateResponse.status === 200) {
113-
localStorage.setItem("user", JSON.stringify(updateResponse.data));
114113
await refetch(); // React Query ์บ์‹œ ๊ฐฑ์‹ 
115114
toast.success("ํ”„๋กœํ•„์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
116115
onClose();

โ€Žsrc/app/components/modal/modals/form/EditOwnerProfileModal.tsxโ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ const EditOwnerProfileModal = ({ isOpen, onClose, className }: EditOwnerProfileM
120120
const updateResponse = await axios.patch("/api/users/me", updateData);
121121

122122
if (updateResponse.status === 200) {
123-
localStorage.setItem("user", JSON.stringify(updateResponse.data));
124123
await refetch(); // React Query ์บ์‹œ ๊ฐฑ์‹ 
125124
toast.success("์‚ฌ์žฅ๋‹˜ ์ •๋ณด๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
126125
onClose();

โ€Žsrc/app/stories/design-system/components/input/picker/DatePicker.stories.tsxโ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ export default meta;
2626
type Story = StoryObj<typeof DatePickerInput>;
2727

2828
export const DatePicker: Story = {
29-
render: () => <DatePickerInput />,
29+
render: () => <DatePickerInput startDateName="startDate" endDateName="endDate" onChange={() => {}} />,
3030
};

0 commit comments

Comments
ย (0)