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
35 changes: 34 additions & 1 deletion apps/client/src/pages/jobPins/JobPins.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
import { Icon } from '@pinback/design-system/icons';
import { Balloon } from '@shared/components/balloon/Balloon';

const JobPins = () => {
return <div>관심 직무 핀 페이지</div>;
return (
<div>
{' '}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

불필요한 {' '} 제거

<div> 직후의 {' '}는 렌더링에 아무런 의미 없는 공백 문자이며, 코드 편집 중 발생한 아티팩트로 보입니다. 제거해 주세요.

🧹 수정 제안
   return (
     <div>
-      {' '}
       <Balloon variant="main" side="bottom">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{' '}
return (
<div>
<Balloon variant="main" side="bottom">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/client/src/pages/jobPins/JobPins.tsx` at line 7, In the JobPins
component (JobPins.tsx) remove the unnecessary JSX whitespace token {' '} that
appears immediately after the <div> element (an artifact of editing) so the
<div> children render without the extraneous blank node; locate the stray {' '}
near the top of the component and delete it leaving the surrounding JSX intact.

<Balloon variant="main" side="bottom">
<div className="text-lg font-semibold">치삐가 방금</div>

<div className="text-sm opacity-90">도토리 1개를 모았어요!</div>
</Balloon>
<Balloon variant="gray" side="left" onClose={() => alert('닫힘')}>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

alert() — 프로덕션 코드에 포함하면 안 되는 임시 핸들러

onClose={() => alert('닫힘')}은 명백히 개발 중 사용하는 임시 코드입니다. alert()은 브라우저 UI를 블로킹하며 프로덕션 환경에 적합하지 않습니다. 실제 닫기 로직이 구현될 때까지 핸들러를 제거하거나 TODO 주석으로 명시해 주세요.

🔧 수정 제안
-      <Balloon variant="gray" side="left" onClose={() => alert('닫힘')}>
+      {/* TODO: 닫기 상태 관리 로직 구현 후 onClose 연결 필요 */}
+      <Balloon variant="gray" side="left">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Balloon variant="gray" side="left" onClose={() => alert('닫힘')}>
{/* TODO: 닫기 상태 관리 로직 구현 후 onClose 연결 필요 */}
<Balloon variant="gray" side="left">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/client/src/pages/jobPins/JobPins.tsx` at line 13, The temporary alert
handler on the Balloon component (onClose={() => alert('닫힘')}) must be removed
or replaced: locate the Balloon usage in JobPins.tsx and either remove the
onClose prop or replace it with a non-blocking stub that clearly marks intent
(e.g., a TODO handler that calls a close function or dispatches a close action)
and add a TODO comment referencing Balloon.onClose to implement real close logic
later; ensure no alert() calls remain in production code.

<div className="text-lg font-semibold">치삐가 방금</div>

<div className="text-sm opacity-90">도토리 1개를 모았어요!</div>
</Balloon>
<Balloon variant="gray" side="left">
<Icon name="ic_info" size={16} />
<div className="text-sm opacity-90">도토리 1개를 모았어요!</div>
</Balloon>
<Balloon variant="main" side="bottom">
<div className="flex items-center gap-3">
{/* 캐릭터 이미지 */}
<Icon name="chippi_profile" size={40} />

{/* 텍스트 영역 */}
<div className="flex flex-col">
<div className="text-[18px] font-semibold">치삐가 방금</div>
<div className="text-[16px]">도토리 1개를 모았어요!</div>
</div>
</div>
</Balloon>
</div>
);
Comment on lines +5 to +35
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check JobPins router registration and actual usage
echo "=== JobPins 라우터 등록 확인 ==="
rg -n "JobPins" --type=tsx --type=ts -g '!node_modules' -C 3

echo "=== 관심 직무 핀 관련 API 연결 여부 ==="
rg -n "jobPin" --type=tsx --type=ts -g '!node_modules' -C 2

Repository: Pinback-Team/pinback-client

Length of output: 198


🏁 Script executed:

#!/bin/bash
# Corrected search - JobPins references in TypeScript/TSX files
echo "=== JobPins 라우터 등록 확인 ==="
rg "JobPins" -g "*.ts" -g "*.tsx" -C 3

echo "=== jobPin 또는 관심 직무 핀 관련 API 연결 여부 ==="
rg "jobPin|job-pin|pin.*job" -g "*.ts" -g "*.tsx" -C 2

echo "=== JobPins 파일 자체 확인 ==="
cat -n apps/client/src/pages/jobPins/JobPins.tsx | head -50

Repository: Pinback-Team/pinback-client

Length of output: 7832


JobPins 페이지가 Balloon 컴포넌트 데모 코드로만 구성되어 있고 실제 기능이 없음

현재 파일은 라우터에 등록되어 있고 사이드바에서 "관심 직무 핀" 메뉴로 접근 가능하지만, 콘텐츠는 Balloon 컴포넌트 쇼케이스의 하드코딩된 예시로만 구성되어 있습니다. "치삐가 방금", "도토리 1개를 모았어요!" 등의 텍스트는 실제 데이터가 아니며, API 연결, 데이터 페칭, 상태 관리가 모두 없는 상태입니다. 실제 관심 직무 핀 기능을 구현하거나, 이 페이지의 목적을 명확히 해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/client/src/pages/jobPins/JobPins.tsx` around lines 5 - 35, The JobPins
page currently contains only hardcoded Balloon demo markup; replace this with
real data fetching and state management: add state (e.g., const [pins, setPins]
= useState<JobPin[]>() ) and a data loader (useEffect or React Query/SWR) that
calls your job pins API (e.g., fetchJobPins or getSavedJobPins) to populate
pins, render the list by mapping pins to <Balloon ...> elements instead of the
static examples, show loading/error UI while fetching, implement onClose
handlers that call an unpin API (e.g., removeJobPin or unpinJob) and update
state optimistically (update setPins to remove the pin on success or rollback on
failure), and ensure prop typings for the JobPins component and children so
Balloon receives the correct title, subtitle, icon, and id values from each pin.

};

export default JobPins;
1 change: 1 addition & 0 deletions apps/client/src/pages/login/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const Login = () => {
</p>

<button
type="button"
onClick={handleGoogleLogin}
className="sub2-sb flex h-[5.2rem] w-[29.8rem] items-center justify-between gap-3 rounded-full border border-gray-100 bg-white px-[2rem]"
>
Expand Down
4 changes: 2 additions & 2 deletions apps/client/src/pages/myBookmark/MyBookmark.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
useDeleteRemindArticle,
usePutArticleReadStatus,
} from '@shared/apis/queries';
import Tooltip from '@shared/components/tooltip/Tooltip';
import TooltipCard from '@shared/components/tooltipCard/TooltipCard';
import ArticlesLoadingBoundary from '@shared/components/articlesLoadingBoundary/ArticlesLoadingBoundary';
import ArticlesErrorBoundary from '@shared/components/articlesErrorBoundary/ArticlesErrorBoundary';
import { ErrorBoundary } from 'react-error-boundary';
Expand Down Expand Up @@ -87,7 +87,7 @@ const MyBookmark = () => {
<p className="head3 text-main500">{category || ''}</p>
</div>

<Tooltip />
<TooltipCard />

<Suspense fallback={<ArticlesLoadingBoundary />}>
<ErrorBoundary FallbackComponent={ArticlesErrorBoundary}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const SocialLoginStep = () => {
</p>

<button
type="button"
onClick={handleGoogleLogin}
className="sub2-sb flex h-[5.2rem] w-[22.7rem] items-center justify-between gap-3 rounded-full border border-gray-100 bg-white px-[2rem]"
>
Expand Down
4 changes: 2 additions & 2 deletions apps/client/src/pages/remind/Remind.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { useQueryClient } from '@tanstack/react-query';
import NoRemindArticles from './components/noRemindArticles/NoRemindArticles';
import FetchCard from './components/fetchCard/FetchCard';
import { useInfiniteScroll } from '@shared/hooks/useInfiniteScroll';
import Tooltip from '@shared/components/tooltip/Tooltip';
import TooltipCard from '@shared/components/tooltipCard/TooltipCard';
import Footer from './components/footer/Footer';

const Remind = () => {
Expand Down Expand Up @@ -138,7 +138,7 @@ const Remind = () => {
isActive={activeBadge === 'read'}
/>
</div>
<Tooltip />
<TooltipCard />

{articlesToDisplay.length > 0 ? (
<div
Expand Down
55 changes: 55 additions & 0 deletions apps/client/src/shared/components/balloon/Balloon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Icon } from '@pinback/design-system/icons';
import { cn } from '@pinback/design-system/utils';
import { ReactNode } from 'react';

type BalloonVariant = 'gray' | 'main';

interface BalloonProps {
variant?: BalloonVariant;
side?: 'top' | 'bottom' | 'left' | 'right';
onClose?: () => void;
children: ReactNode;
}

export function Balloon({
variant = 'gray',
side = 'bottom',
onClose,
children,
}: BalloonProps) {
const variantStyle = {
gray: 'bg-gray900 text-white',
main: 'bg-main500 text-white',
};

return (
<div className="relative inline-block">
<div
className={cn(
'relative flex items-start gap-3 rounded-[4px] p-[1.2rem]',
variantStyle[variant]
)}
>
<div className="flex-1">{children}</div>

{onClose && (
<button type="button" onClick={onClose}>
<Icon name="ic_close" size={16} />
</button>
)}
Comment on lines 35 to 39
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

닫기 버튼에 aria-labeltype="button" 속성 누락

onClose 조건부 버튼에 두 가지 문제가 있습니다.

  1. aria-label이 없어 스크린 리더 사용자가 버튼의 목적을 인식할 수 없습니다.
  2. type="button"이 없어, 이 컴포넌트가 <form> 내부에서 사용될 경우 기본값인 type="submit"으로 동작하여 의도치 않은 폼 제출이 발생할 수 있습니다.
♿ 수정 제안
-        <button onClick={onClose}>
+        <button type="button" aria-label="닫기" onClick={onClose}>
           <Icon name="ic_close" size={16} />
         </button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{onClose && (
<button onClick={onClose}>
<Icon name="ic_close" size={16} />
</button>
)}
{onClose && (
<button type="button" aria-label="닫기" onClick={onClose}>
<Icon name="ic_close" size={16} />
</button>
)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/client/src/shared/components/balloon/Balloon.tsx` around lines 34 - 38,
조건부로 렌더되는 닫기 버튼 (onClose 핸들러와 함께 렌더되는 <button> 바로 그 요소)에 accessibility와 form 동작
문제를 고치기 위해 버튼에 명시적 type="button" 속성을 추가하고 스크린 리더용 aria-label을 추가하세요 (예:
aria-label="닫기" 또는 컴포넌트에 전달되는 레이블 prop 사용). 변경 대상 식별자: onClose 조건부 버튼 렌더링과 Icon
name="ic_close" 사용 부분(Balloon.tsx의 해당 버튼)을 찾아 해당 요소에 type="button"과 적절한
aria-label을 설정하면 됩니다.

</div>

{/* 꼬리 */}
<div
className={cn(
'absolute h-[12px] w-[12px] rotate-45',
variantStyle[variant],
side === 'bottom' && '-bottom-1 left-1/2 -translate-x-1/2',
side === 'top' && '-top-1 left-1/2 -translate-x-1/2',
side === 'left' && '-left-1 top-1/2 -translate-y-1/2',
side === 'right' && '-right-1 top-1/2 -translate-y-1/2'
)}
/>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Icon } from '@pinback/design-system/icons';
import InfoCard from './InfoCard';

export default function Tooltip() {
export default function TooltipCard() {
return (
<div className="mt-[0.8rem] flex items-center">
<p className="body3-r text-font-gray-3">
Expand Down
Loading