Skip to content

Commit 7c709c4

Browse files
committed
feat(getcloser): display id and username instead of email
1 parent 67410c3 commit 7c709c4

6 files changed

Lines changed: 86 additions & 41 deletions

File tree

getcloser/frontend/src/app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import type { Metadata } from "next";
3+
44
import { Geist, Geist_Mono, Dongle } from "next/font/google";
55
import "./globals.css";
66
import { Providers } from './providers';

getcloser/frontend/src/app/page1/page.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
'use client';
22

3-
import Link from 'next/link';
43
import Image from 'next/image';
54
import { Button } from '@/components/ui/button';
65
import { Input } from '@/components/ui/input';
76
import { Label } from '@/components/ui/label';
87
import { useFormStore } from '../../store/formStore';
9-
import { Rows } from 'lucide-react';
108

119
import { useRouter } from 'next/navigation';
1210

1311
export default function Page1() {
14-
const { email, setEmail } = useFormStore();
12+
const { email, setEmail, setId } = useFormStore();
1513
const router = useRouter();
1614

1715
const handleSubmit = async (e: React.FormEvent) => {
@@ -33,6 +31,9 @@ export default function Page1() {
3331

3432
const result = await response.json();
3533
console.log('Auth API Response:', result);
34+
if (result.id) {
35+
setId(result.id); // Store the ID in the form store
36+
}
3637
alert('정보가 제출되었습니다!');
3738
router.push('/page2'); // Navigate to page2 after successful submission
3839
} catch (error) {
@@ -49,7 +50,7 @@ export default function Page1() {
4950
<div className="items-center text-center" style={{marginBottom: 36}}>
5051
<p className="text-md mt-1">Pseudo Lab</p>
5152
<p className="text-md">2nd Grand Gathering</p>
52-
<p className="text-md">2025. 11. 15</p>
53+
<p className="text-md">2025. 12. 20</p>
5354
</div>
5455
<form className="space-y-4" onSubmit={handleSubmit}>
5556
<div className='items-center text-center'>

getcloser/frontend/src/app/page2/page.tsx

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import React, { useState, useEffect, useRef } from 'react';
3+
import React, { useState, useEffect, useRef, useCallback } from 'react';
44
import Link from 'next/link';
55
import { useRouter } from 'next/navigation';
66
import { Button } from '@/components/ui/button';
@@ -11,25 +11,60 @@ import Modal from '@/components/Modal';
1111
import Cookies from 'js-cookie';
1212

1313
export default function Page2() {
14-
const { email } = useFormStore();
14+
const { id } = useFormStore();
1515
const router = useRouter();
16-
const [inputs, setInputs] = useState<string[]>(() => {
17-
const initialInputs = Array(5).fill('');
18-
if (email) {
19-
initialInputs[0] = email;
20-
}
16+
const [inputs, setInputs] = useState<Array<{ id: string; displayName: string }>>(() => {
17+
const initialInputs = Array(5).fill({ id: '', displayName: '' });
2118
return initialInputs;
2219
});
2320
const [showModal, setShowModal] = useState(false);
2421
const timeoutRef = useRef<NodeJS.Timeout | null>(null); // Add timeoutRef
2522

23+
const fetchUserById = useCallback(async (index: number, userId: string) => {
24+
if (!userId) return; // Don't fetch if ID is empty
25+
26+
// Prevent adding self as a team member
27+
if (index !== 0 && id && Number(userId) === Number(id)) { // Check only for other team members, not self
28+
alert(`자기 자신(${userId})을 팀원으로 추가할 수 없습니다.`);
29+
const newInputs = [...inputs];
30+
newInputs[index] = { id: '', displayName: '' }; // Clear the input field
31+
setInputs(newInputs);
32+
return;
33+
}
34+
35+
try {
36+
const response = await fetch(`/api/v1/users/${userId}`);
37+
if (!response.ok) {
38+
throw new Error(`HTTP error! status: ${response.status}`);
39+
}
40+
const userData = await response.json();
41+
// Assuming the API returns an object with a 'data' field which is the display name
42+
const newInputs = [...inputs];
43+
newInputs[index] = { id: userId, displayName: userData.data || userId }; // Store both id and display name
44+
setInputs(newInputs);
45+
} catch (error) {
46+
console.error(`Error fetching user ${userId}:`, error);
47+
const newInputs = [...inputs];
48+
newInputs[index] = { id: userId, displayName: userId }; // Fallback to just ID if fetch fails
49+
setInputs(newInputs);
50+
// Optionally, display an error message to the user
51+
}
52+
}, [id, inputs]);
53+
2654
useEffect(() => {
2755
const hasSeenModal = Cookies.get('doNotShowModalPage2');
2856
if (!hasSeenModal) {
2957
setShowModal(true);
3058
}
3159
}, []);
3260

61+
// Effect to pre-fill the first input if ID is available
62+
useEffect(() => {
63+
if (id && inputs[0].id === '') { // Only fetch if ID exists and input is empty
64+
fetchUserById(0, id);
65+
}
66+
}, [id, fetchUserById, inputs]); // Rerun when id changes
67+
3368
const handleConfirm = () => {
3469
setShowModal(false);
3570
};
@@ -41,7 +76,7 @@ export default function Page2() {
4176

4277
const handleInputChange = (index: number, value: string) => {
4378
const newInputs = [...inputs];
44-
newInputs[index] = value;
79+
newInputs[index] = { id: value, displayName: value }; // Temporarily set display name to ID
4580
setInputs(newInputs);
4681

4782
// Clear any existing timeout
@@ -55,26 +90,8 @@ export default function Page2() {
5590
}, 3000);
5691
};
5792

58-
const fetchUserById = async (index: number, id: string) => {
59-
if (!id) return; // Don't fetch if ID is empty
60-
try {
61-
const response = await fetch(`${process.env.APP_HOST}/v1/users/${id}`);
62-
if (!response.ok) {
63-
throw new Error(`HTTP error! status: ${response.status}`);
64-
}
65-
const userData = await response.json();
66-
// Assuming the API returns an object with a 'detail' field as per user's confirmation
67-
const newInputs = [...inputs];
68-
newInputs[index] = userData.detail || id; // Use fetched detail, or original ID if not found
69-
setInputs(newInputs);
70-
} catch (error) {
71-
console.error(`Error fetching user ${id}:`, error);
72-
// Optionally, display an error message to the user
73-
}
74-
};
75-
7693
const handleSolveProblem = () => {
77-
console.log('Inputs:', inputs);
94+
console.log('Inputs:', inputs.map(input => input.id));
7895
// You can add logic here to process the inputs before navigating
7996
router.push('/page3');
8097
};
@@ -95,7 +112,6 @@ export default function Page2() {
95112
onDoNotShowAgain={handleDoNotShowAgain}
96113
isOpen={showModal}
97114
/>
98-
{email && <p className="mt-4">이메일: <strong>{email}</strong></p>}
99115

100116
<div className="mt-8 space-y-4">
101117
{[...Array(5)].map((_, index) => (
@@ -106,13 +122,13 @@ export default function Page2() {
106122
id={`team-id-${index}`}
107123
type="id"
108124
placeholder={`팀원 ${index + 1}의 번호`}
109-
value={inputs[index]}
125+
value={inputs[index].displayName}
110126
onChange={(e) => handleInputChange(index, e.target.value)}
111-
onBlur={(e) => {
127+
onBlur={() => {
112128
if (timeoutRef.current) {
113129
clearTimeout(timeoutRef.current); // Clear any pending debounce
114130
}
115-
fetchUserById(index, e.target.value); // Fetch immediately on blur
131+
fetchUserById(index, inputs[index].id); // Fetch immediately on blur using the stored ID
116132
}}
117133
disabled={index === 0}
118134
/>
Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,43 @@
11
'use client';
22

3-
import React from 'react';
3+
import React, { useState, useEffect } from 'react';
44
import { useFormStore } from '../store/formStore';
55

66
export default function Header() {
7-
const { email } = useFormStore();
7+
const { id } = useFormStore();
8+
const [userName, setUserName] = useState<string | null>(null);
9+
10+
useEffect(() => {
11+
if (id) {
12+
const fetchUserName = async () => {
13+
try {
14+
const response = await fetch(`/api/v1/users/${id}`);
15+
if (!response.ok) {
16+
throw new Error(`HTTP error! status: ${response.status}`);
17+
}
18+
const userData = await response.json();
19+
setUserName(userData.data || null);
20+
} catch (error) {
21+
console.error(`Error fetching user ${id}:`, error);
22+
setUserName(null); // Clear user name on error
23+
}
24+
};
25+
fetchUserName();
26+
} else {
27+
setUserName(null); // Clear user name if id is empty
28+
}
29+
}, [id]);
830

931
return (
1032
<header className="py-4 bg-background text-foreground border-b border-border">
1133
<h1 className="text-3xl font-bold">친해지길바라</h1>
1234
<p className="text-md mt-1 text-center" style={{ margin: 0, padding: 0, lineHeight: '1em' }}>
1335
Pseudo Lab<br />
1436
2nd Grand Gathering<br />
15-
2025. 11. 15
37+
2025. 12. 20
1638
</p>
17-
{email && <p className="text-sm mt-2"><strong>{email}</strong></p>}
39+
{id && userName && <p className="text-sm mt-2">ID: <strong>{id}</strong>, 이름: <strong>{userName}</strong></p>}
40+
{id && !userName && <p className="text-sm mt-2">ID: <strong>{id}</strong></p>}
1841
</header>
1942
);
2043
}

getcloser/frontend/src/store/formStore.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,22 @@ import { create } from 'zustand';
22

33
interface FormState {
44
email: string;
5+
id: string;
56
question: string;
67
answer: string;
78
setEmail: (email: string) => void;
9+
setId: (id: string) => void;
810
setQuestion: (question: string) => void;
911
setAnswer: (answer: string) => void;
1012
}
1113

1214
export const useFormStore = create<FormState>((set) => ({
1315
email: '',
16+
id: '',
1417
question: '',
1518
answer: '',
1619
setEmail: (email) => set({ email }),
20+
setId: (id) => set({ id }),
1721
setQuestion: (question) => set({ question }),
1822
setAnswer: (answer) => set({ answer }),
1923
}));

getcloser/frontend/tailwind.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Config } from 'tailwindcss';
22
import defaultTheme from 'tailwindcss/defaultTheme';
3+
import tailwindAnimate from 'tailwindcss-animate';
34

45
const config: Config = {
56
darkMode: false,
@@ -79,7 +80,7 @@ const config: Config = {
7980
},
8081
},
8182
},
82-
plugins: [require('tailwindcss-animate')],
83+
plugins: [tailwindAnimate],
8384
};
8485

8586
export default config;

0 commit comments

Comments
 (0)