Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
48af498
feat: Comment 인터페이스 수정 및 필드 추가
Monixc Aug 9, 2025
cd02b91
feat: NearbyUser 및 관련 인터페이스 추가, Post 인터페이스에 content 필드 추가
Monixc Aug 9, 2025
a1cf54b
feat: 게시글 상세 조회 및 댓글 관련 API 추가
Monixc Aug 9, 2025
36d0e3f
feat: 댓글 생성 API 제거
Monixc Aug 9, 2025
cc881f5
feat: usePost 훅 삭제 및 관련 API 통합
Monixc Aug 9, 2025
894b192
feat: 게시글 상세 페이지 및 날짜 형식화 기능 추가
Monixc Aug 9, 2025
27f9854
feat: useDebounce 훅 추가
Monixc Aug 9, 2025
436e33d
feat: 검색 기능 및 최근 검색어 관리 훅 추가
Monixc Aug 9, 2025
a18ee51
feat: 커뮤니티 관련 타입 정의 수정 및 추가
Monixc Aug 10, 2025
eb2ac0f
feat: 게시글 및 댓글 관련 기능 추가 및 타입 수정
Monixc Aug 10, 2025
683382a
chore: alert-dialong, dropdwon-menu 설치치
Monixc Aug 10, 2025
b5f83a4
feat: 포지션 선택기 및 게시글 관련 기능 개선
Monixc Aug 10, 2025
1e9a9e3
feat: 게시글 작성 및 목록 표시 기능 개선
Monixc Aug 10, 2025
7941b0f
feat: 게시글 타입 수정 및 클릭 핸들러 업데이트
Monixc Aug 10, 2025
5de87f5
feat: 프로필 편집 기능 및 API 연동 추가
Monixc Aug 10, 2025
24df53d
feat: 하단 내비게이션 표시 조건 수정
Monixc Aug 10, 2025
4924968
feat: ListItem 컴포넌트 common으로 이동
Monixc Aug 11, 2025
90b2263
feat: 메뉴 항목 및 프로필 탭 수정
Monixc Aug 11, 2025
9b508b1
feat: 회원가입 후 네비게이션 및 버튼 텍스트 수정
Monixc Aug 11, 2025
9d6eab8
feat: 불필요한 Save 임포트 제거
Monixc Aug 11, 2025
57410af
feat: 쿼리 훅의 staleTime을 0으로 변경 및 불필요한 데이터 업데이트 로직 제거
Monixc Aug 11, 2025
2268e53
feat: 위치 정보 가져오기 에러 처리 추가
Monixc Aug 11, 2025
d821c67
feat: 내 프로필 관련 페이지 및 API 기능 추가
Monixc Aug 11, 2025
4e68f19
feat: 임포트 수정
Monixc Aug 11, 2025
9c9c7c1
feat: 지원자 클릭 시 프로필 페이지로 네비게이션 추가
Monixc Aug 11, 2025
5d87f01
feat: 개발자 관련 API 및 쿼리 훅 추가
Monixc Aug 11, 2025
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
101 changes: 100 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@
},
"dependencies": {
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-alert-dialog": "^1.1.14",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-select": "^2.2.5",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slider": "^1.3.5",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-toggle": "^1.1.0",
"@tanstack/react-query": "^5.83.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Heart, MessageCircle } from "lucide-react";
import { Heart, MessageCircle, Users } from "lucide-react";
import { useNavigate } from "react-router-dom";
import type { Post } from "@/types/post.types";
import type { PostListItem } from "@/types/post.types";
import { formatPostListDate } from "@/lib/date";

interface ListItemProps {
post: Post;
post: PostListItem;
}

export const ListItem = ({ post }: ListItemProps) => {
Expand All @@ -15,14 +16,6 @@ export const ListItem = ({ post }: ListItemProps) => {
navigate(`/community/${post.id}`);
};

const formatDate = (dateString: string) => {
const date = new Date(dateString);
return date.toLocaleDateString("ko-KR", {
month: "short",
day: "numeric",
});
};

return (
<Card
className="bg-brand-surface border-none text-white hover:bg-brand-surface/50 transition-colors cursor-pointer"
Expand All @@ -35,17 +28,27 @@ export const ListItem = ({ post }: ListItemProps) => {
</CardHeader>
<CardContent className="flex justify-between items-center text-xs text-brand-text">
<span>
{post.author.nickname} · {formatDate(post.createdAt)}
{post.author.nickname} · {formatPostListDate(post.createdAt)}
</span>
<div className="flex items-center space-x-4">
<div className="flex items-center space-x-1">
<Heart className="size-4" aria-label="좋아요" />
<span className="w-3">{post.nLikes}</span>
</div>
<div className="flex items-center space-x-1">
<MessageCircle className="size-4" aria-label="댓글" />
<span className="w-3">{post.nComments}</span>
</div>
{/* 일반 게시판: 댓글 개수 표시 */}
{!post.board.isRecruit && (
<div className="flex items-center space-x-1">
<MessageCircle className="size-4" aria-label="댓글" />
<span className="w-3">{post.nComments}</span>
</div>
)}
{/* 모집 게시판: 지원자 개수 표시. api에 관련 필드 없는 관계로 쿼리로 처리 중--개선 필요*/}
{post.board.isRecruit && (
<div className="flex items-center space-x-1">
<Users className="size-4" aria-label="지원자" />
<span className="w-3">{post.nApplicants || 0}</span>
</div>
)}
</div>
</CardContent>
</Card>
Expand Down
53 changes: 38 additions & 15 deletions src/components/common/PositionSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,20 @@ import type { Position } from "@/types/tags.types";

interface PositionSelectorProps {
selectedPosition: number | null;
selectedPositionIds?: number[];
onPositionChange: (positionId: number) => void;
onPositionIdsChange?: (positionIds: number[]) => void;
label?: string;
multiple?: boolean;
}

export const PositionSelector = ({
selectedPosition,
selectedPositionIds = [],
onPositionChange,
onPositionIdsChange,
label = "포지션",
multiple = false,
}: PositionSelectorProps) => {
const { data: positionsInterestsData, isLoading } = usePositionsInterests();

Expand Down Expand Up @@ -59,21 +65,38 @@ export const PositionSelector = ({
</AccordionTrigger>
<AccordionContent>
<div className="flex flex-col gap-2 pt-2">
{fieldPositions.map((position) => (
<Button
key={position.id}
variant="outline"
onClick={() => onPositionChange(position.id)}
className={cn(
"h-auto justify-start text-left whitespace-normal border-transparent bg-brand-surface",
selectedPosition === position.id &&
"border-brand-primary text-brand-primary border-1"
)}>
<div className="flex flex-col">
<span className="font-bold">{position.role}</span>
</div>
</Button>
))}
{fieldPositions.map((position) => {
const isSelected = multiple
? selectedPositionIds.includes(position.id)
: selectedPosition === position.id;

const handleClick = () => {
if (multiple && onPositionIdsChange) {
const newPositionIds = isSelected
? selectedPositionIds.filter((id) => id !== position.id)
: [...selectedPositionIds, position.id];
onPositionIdsChange(newPositionIds);
} else {
onPositionChange(position.id);
}
};

return (
<Button
key={position.id}
variant="outline"
onClick={handleClick}
className={cn(
"h-auto justify-start text-left whitespace-normal border-transparent bg-brand-surface",
isSelected &&
"border-brand-primary text-brand-primary border-1"
)}>
<div className="flex flex-col">
<span className="font-bold">{position.role}</span>
</div>
</Button>
);
})}
</div>
</AccordionContent>
</AccordionItem>
Expand Down
7 changes: 4 additions & 3 deletions src/components/layout/GlobalLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ interface GlobalLayoutProps {
function GlobalLayout({ children }: GlobalLayoutProps) {
const location = useLocation();

const shouldShowBottomNav = ["/board", "/explore", "/chat", "/my"].some(
(path) => location.pathname.startsWith(path)
);
const shouldShowBottomNav =
["/board", "/explore", "/chat", "/my"].some((path) =>
location.pathname.startsWith(path)
) && !location.pathname.startsWith("/my/edit");

return (
<div className="min-h-screen bg-slate-100 flex justify-center">
Expand Down
Loading