Skip to content

Commit bb1bb59

Browse files
authored
Merge branch 'dev' into feat/132-chatRoom-leftButton
2 parents 3b29016 + ce09233 commit bb1bb59

6 files changed

Lines changed: 112 additions & 54 deletions

File tree

.github/workflows/java-style-check.yml

Lines changed: 0 additions & 18 deletions
This file was deleted.

.github/workflows/style-check.yml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
name: Java Style Check
2+
3+
on:
4+
push:
5+
branches-ignore:
6+
- main
7+
- dev
8+
9+
jobs:
10+
java-style:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- name: Run Google Java Format
15+
uses: axel-op/googlejavaformat-action@v4
16+
with:
17+
args: "--replace --aosp"
18+
commit-message: "chore: Java 스타일 수정"
19+
20+
kotlin-style:
21+
needs: java-style
22+
permissions:
23+
contents: write
24+
statuses: write
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v4
28+
with:
29+
fetch-depth: 0
30+
31+
- name: Super-Linter
32+
uses: super-linter/super-linter@v7.4.0
33+
env:
34+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35+
FIX_KOTLIN: true
36+
DISABLE_ERRORS: true
37+
VALIDATE_BASH: false
38+
VALIDATE_BASH_EXEC: false
39+
VALIDATE_CHECKOV: false
40+
VALIDATE_GITHUB_ACTIONS: false
41+
VALIDATE_GITLEAKS: false
42+
VALIDATE_GIT_MERGE_CONFLICT_MARKERS: false
43+
VALIDATE_JSCPD: false
44+
VALIDATE_SHELL_SHFMT: false
45+
VALIDATE_YAML: false
46+
VALIDATE_YAML_PRETTIER: false
47+
VALIDATE_GOOGLE_JAVA_FORMAT: false
48+
VALIDATE_JAVA: false
49+
VALIDATE_CSS: false
50+
VALIDATE_CSS_PRETTIER: false
51+
VALIDATE_DOCKERFILE_HADOLINT: false
52+
VALIDATE_GROOVY: false
53+
VALIDATE_HTML: false
54+
VALIDATE_HTML_PRETTIER: false
55+
VALIDATE_JAVASCRIPT_ES: false
56+
VALIDATE_JAVASCRIPT_PRETTIER: false
57+
VALIDATE_JAVASCRIPT_STANDARD: false
58+
VALIDATE_JSON: false
59+
VALIDATE_JSON_PRETTIER: false
60+
VALIDATE_MARKDOWN: false
61+
VALIDATE_MARKDOWN_PRETTIER: false
62+
VALIDATE_NATURAL_LANGUAGE: false
63+
VALIDATE_SQLFLUFF: false
64+
VALIDATE_TSX: false
65+
VALIDATE_TYPESCRIPT_ES: false
66+
VALIDATE_TYPESCRIPT_PRETTIER: false
67+
VALIDATE_TYPESCRIPT_STANDARD: false
68+
69+
- name: Commit and push linting fixes
70+
uses: stefanzweifel/git-auto-commit-action@v5
71+
with:
72+
branch: ${{ github.ref_name }}
73+
commit_message: "chore: Kotlin 스타일 수정"
74+
commit_user_name: super-linter
75+
commit_user_email: super-linter@super-linter.dev

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
### Super Linter ###
2+
.super-linter.report/
3+
super-linter-summary.md
4+
branch_protection_rules.json

NBE_5_7_2_02TEAM/build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ dependencies {
2828
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
2929
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
3030
implementation 'org.springframework.boot:spring-boot-starter-security'
31-
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
3231
implementation 'org.springframework.boot:spring-boot-starter-web'
3332
implementation 'org.springframework.boot:spring-boot-starter-validation'
3433
implementation 'org.springframework.boot:spring-boot-starter-websocket'
@@ -48,7 +47,6 @@ dependencies {
4847
/* ETC */
4948
compileOnly 'org.projectlombok:lombok'
5049
annotationProcessor 'org.projectlombok:lombok'
51-
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
5250
implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
5351
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6'
5452
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'

frontend/src/components/ChatRoom.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ interface ChatRes {
4141
interface ServerChatItem {
4242
id: number
4343
member_id: number
44-
member_name: string // 서버 응답에 이 필드가 포함되어야 가장 좋습니다.
44+
member_name: string
4545
content: string
4646
created_at: string
4747
}
@@ -90,16 +90,14 @@ function ChatRoom({ chatRoomId, postTitle, onBack }: ChatRoomProps) {
9090
const token = localStorage.getItem("accessToken");
9191
if (token) {
9292
const payload = decodeJwtPayload(token);
93-
// Assuming the memberId is stored in a claim named 'memberId' or 'sub' (standard for subject)
94-
// Adjust 'memberId' or 'sub' based on your actual JWT payload structure
9593
if (payload && payload.memberId) {
9694
setCurrentMemberId(Number(payload.memberId));
97-
} else if (payload && payload.sub) { // Fallback to 'sub' if 'memberId' is not present
95+
} else if (payload && payload.sub) {
9896
setCurrentMemberId(Number(payload.sub));
9997
}
10098
} else {
10199
}
102-
}, []); // Run once on component mount
100+
}, []);
103101

104102
const scrollToBottom = () => {
105103
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
@@ -152,7 +150,7 @@ function ChatRoom({ chatRoomId, postTitle, onBack }: ChatRoomProps) {
152150
const mappedResult: ChatRes[] = resultFromServer.map((item) => ({
153151
id: item.id,
154152
memberId: item.member_id,
155-
memberName: item.member_name, // 초기 로딩 시에는 서버가 이름을 줄 것으로 기대
153+
memberName: item.member_name,
156154
content: item.content,
157155
createdAt: new Date(item.created_at),
158156
}));
@@ -247,7 +245,7 @@ function ChatRoom({ chatRoomId, postTitle, onBack }: ChatRoomProps) {
247245
const mappedData: ChatRes = {
248246
id: serverData.id,
249247
memberId: serverData.member_id,
250-
memberName: memberName, // 수정된 이름 사용
248+
memberName: memberName,
251249
content: serverData.content,
252250
createdAt: new Date(serverData.created_at),
253251
};
@@ -467,7 +465,6 @@ function ChatRoom({ chatRoomId, postTitle, onBack }: ChatRoomProps) {
467465
<line x1="21" y1="12" x2="9" y2="12" />
468466
</svg>
469467
</button>
470-
471468
</div>
472469

473470
<div className="flex-grow p-2">

frontend/src/pages/ChatRoomList.tsx

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import { Skeleton } from "@/components/ui/skeleton";
99
// 2a. 서버 응답 객체의 인터페이스 (스네이크 케이스)
1010
interface ServerChatRoom {
1111
id: number;
12-
post_id: number; // 서버에서 오는 필드명
12+
post_id: number;
1313
title: string;
14+
member_count: number;
15+
updated_at: Date;
1416
}
1517

1618
function ChatRoomList() {
@@ -21,19 +23,16 @@ function ChatRoomList() {
2123
const [selectedRoom, setSelectedRoom] = useState<number | null>(null);
2224
const [selectedRoomTitle, setSelectedRoomTitle] = useState("");
2325

24-
2526
const fetchData = async () => {
2627
setLoading(true);
2728
setError(null);
28-
const token = localStorage.getItem("accessToken"); // 토큰 가져오기
29+
const token = localStorage.getItem("accessToken");
2930

3031
if (!token) {
3132
console.error("[fetchData] Authorization token not found in localStorage.");
3233
setError("로그인이 필요합니다. 로그인 후 다시 시도해주세요.");
3334
setLoading(false);
3435
setItems([]);
35-
// 여기서 로그인 페이지로 리디렉션하거나 사용자에게 명확한 안내를 할 수 있습니다.
36-
// 예: router.push('/login'); (Next.js 사용 시)
3736
return;
3837
}
3938

@@ -42,18 +41,16 @@ function ChatRoomList() {
4241
cache: "no-store",
4342
headers: {
4443
"Content-Type": "application/json",
45-
"Authorization": `Bearer ${token}`, // Authorization 헤더 추가
44+
"Authorization": `Bearer ${token}`,
4645
},
4746
});
4847

4948
if (!res.ok) {
5049
if (res.status === 401 || res.status === 403) {
51-
const errorText = await res.text(); // 에러 본문을 읽어옴 (JSON 형태일 수도 있음)
50+
const errorText = await res.text();
5251
console.error(`[fetchData] Authentication error (${res.status}):`, errorText);
5352
setError(`인증에 실패했습니다 (${res.status}). 세션이 만료되었거나 권한이 없습니다. 다시 로그인해주세요.`);
54-
// 필요하다면 여기서 로그아웃 처리 또는 로그인 페이지로 강제 이동
5553
} else {
56-
// 기타 HTTP 에러
5754
const errorText = await res.text();
5855
console.error(`[fetchData] HTTP error! status: ${res.status}, message: ${errorText}`);
5956
throw new Error(`HTTP error! status: ${res.status}, message: ${errorText}`);
@@ -66,15 +63,20 @@ function ChatRoomList() {
6663
const responseData: ServerChatRoom[] = await res.json();
6764

6865
if (responseData && Array.isArray(responseData)) {
69-
setItems(responseData);
66+
const sortedData = responseData.map(room => ({
67+
...room,
68+
updated_at: new Date(room.updated_at)
69+
})).sort((a, b) => {
70+
return b.updated_at.getTime() - a.updated_at.getTime()
71+
});
72+
setItems(sortedData);
7073
} else {
7174
setItems([]);
7275
console.warn("[fetchData] API 응답에서 data 필드를 찾을 수 없거나 형식이 배열이 아닙니다.", responseData);
7376
setError("채팅방 목록을 가져오는 데 실패했습니다. (응답 데이터 형식 오류)");
7477
}
7578
} catch (e: any) {
7679
console.error("[fetchData] 채팅방 목록을 가져오는 중 오류 발생: ", e);
77-
// 네트워크 에러 등의 경우 e.message가 있을 수 있음
7880
setError(e.message || "알 수 없는 오류가 발생했습니다. 네트워크 연결을 확인해주세요.");
7981
setItems([]);
8082
} finally {
@@ -84,7 +86,7 @@ function ChatRoomList() {
8486

8587
useEffect(() => {
8688
fetchData();
87-
}, [retryCount]); // retryCount 변경 시 fetchData 재호출
89+
}, [retryCount]);
8890

8991
const handleRetry = () => {
9092
setRetryCount((prev) => prev + 1);
@@ -103,16 +105,16 @@ function ChatRoomList() {
103105

104106
return (
105107
<div className="flex h-[calc(100vh-4rem)] bg-[#f0f2f5] overflow-hidden p-4">
106-
<div className={`transition-all duration-300 ease-in-out ${selectedRoom ? "w-1/3 md:w-1/4 lg:w-1/5" : "w-full"}`}>
108+
<div className={`transition-all duration-300 ease-in-out ${selectedRoom ? "w-[280px] min-w-[280px]" : "w-full"}`}>
107109
<div className="h-full flex flex-col max-w-[480px] mx-auto">
108110
<div className="flex-grow overflow-hidden rounded-xl bg-white shadow-lg flex flex-col">
109-
<div className="flex flex-col xl:flex-row xl:items-center justify-between p-4 border-b border-[#e4e6eb]">
110-
<h1 className="text-xl font-bold text-[#1877f2] mb-2 xl:mb-0">참여중인 채팅방 목록</h1>
111+
<div className="flex flex-col p-4 border-b border-[#e4e6eb]">
112+
<h1 className="text-xl font-bold text-[#1877f2] mb-3 whitespace-nowrap truncate">참여중인 채팅방 목록</h1>
111113
<Button
112114
variant="outline"
113115
onClick={handleRetry}
114116
disabled={loading}
115-
className="flex items-center gap-2 text-[#1877f2] border-[#e4e6eb] hover:bg-[#f0f2f5] w-full xl:w-auto"
117+
className="flex items-center gap-2 text-[#1877f2] border-[#e4e6eb] hover:bg-[#f0f2f5] w-full"
116118
>
117119
<RefreshIcon className="h-4 w-4" />
118120
새로고침
@@ -172,8 +174,8 @@ function ChatRoomList() {
172174
</div>
173175
)}
174176
</div>
175-
</div >
176-
);
177+
</div>
178+
)
177179
}
178180

179181
function ChatRoomSkeleton() {
@@ -185,10 +187,10 @@ function ChatRoomSkeleton() {
185187
</div>
186188
<Skeleton className="h-4 w-32 mt-2" />
187189
</div>
188-
);
190+
)
189191
}
190192

191-
function RefreshIcon(props: React.SVGProps<SVGSVGElement>) { // props 타입 추가
193+
function RefreshIcon(props: React.SVGProps<SVGSVGElement>) {
192194
return (
193195
<svg
194196
xmlns="http://www.w3.org/2000/svg"
@@ -205,10 +207,10 @@ function RefreshIcon(props: React.SVGProps<SVGSVGElement>) { // props 타입 추
205207
<path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" />
206208
<path d="M3 21v-5h5" />
207209
</svg>
208-
);
210+
)
209211
}
210212

211-
function AlertCircleIcon(props: React.SVGProps<SVGSVGElement>) { // props 타입 추가
213+
function AlertCircleIcon(props: React.SVGProps<SVGSVGElement>) {
212214
return (
213215
<svg
214216
xmlns="http://www.w3.org/2000/svg"
@@ -224,10 +226,10 @@ function AlertCircleIcon(props: React.SVGProps<SVGSVGElement>) { // props 타입
224226
<line x1="12" y1="8" x2="12" y2="12" />
225227
<line x1="12" y1="16" x2="12.01" y2="16" />
226228
</svg>
227-
);
229+
)
228230
}
229231

230-
function ChatBubbleIcon(props: React.SVGProps<SVGSVGElement>) { // props 타입 추가
232+
function ChatBubbleIcon(props: React.SVGProps<SVGSVGElement>) {
231233
return (
232234
<svg
233235
xmlns="http://www.w3.org/2000/svg"
@@ -242,7 +244,7 @@ function ChatBubbleIcon(props: React.SVGProps<SVGSVGElement>) { // props 타입
242244
<path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v5Z" />
243245
<path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1" />
244246
</svg>
245-
);
247+
)
246248
}
247249

248-
export default ChatRoomList;
250+
export default ChatRoomList

0 commit comments

Comments
 (0)