diff --git a/src/App.tsx b/src/App.tsx index 124eb5b..bc3affb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,26 +1,8 @@ import { Outlet } from "react-router-dom"; import GlobalLayout from "./components/layout/GlobalLayout"; -import { OnboardingPage } from "./pages/onboarding/OnboardingPage"; - function App() { - const path = window.location.pathname; - - let content; - if (path === '/onboarding') { - content = ; - } else { - content = ( - <> -

brand-primary 색상 테스트

-

brand 색상 테스트

-
- 온보딩 페이지 테스트 - - ); - } - return ( - + ); diff --git a/src/components/common/AppTabs.tsx b/src/components/common/AppTabs.tsx index 337a46a..3f728c6 100644 --- a/src/components/common/AppTabs.tsx +++ b/src/components/common/AppTabs.tsx @@ -6,25 +6,28 @@ interface Tab { label: string; } -interface AppTabsProps { - tabs: readonly Tab[]; - value: string; - onValueChange: (value: string) => void; +interface AppTabsProps { + tabs: readonly (Tab & { value: T })[]; + value: T; + onValueChange: (value: T) => void; listClassName?: string; triggerClassName?: string; className?: string; } -export const AppTabs = ({ +export const AppTabs = ({ tabs, value, onValueChange, listClassName, triggerClassName, className, -}: AppTabsProps) => { +}: AppTabsProps) => { return ( - + onValueChange(value as T)} + className={cn(className)}> { + const fileInputRef = useRef(null); + const [imagePreview, setImagePreview] = useState(null); + + const handleImageClick = () => { + if (!isEditable) return; + fileInputRef.current?.click(); + }; + + const handleFileChange = (event: React.ChangeEvent) => { + const file = event.target.files?.[0]; + if (file) { + const reader = new FileReader(); + + reader.onloadend = () => { + if (typeof reader.result === "string") { + setImagePreview(reader.result); + } + }; + reader.readAsDataURL(file); + } + }; + + return ( +
+
+
+ {imagePreview ? ( + Profile preview + ) : ( + isEditable && + )} +
+ {isEditable && ( + + )} +
+

이름

+

나이 · 포지션

+ {isEditable && ( + + )} +
+ ); +}; diff --git a/src/constants/my.ts b/src/constants/my.ts new file mode 100644 index 0000000..1e89c6c --- /dev/null +++ b/src/constants/my.ts @@ -0,0 +1,8 @@ +export const MENU_ITEMS = [ + { id: "posts", label: "작성한 글" }, + { id: "history", label: "활동 이력" }, + { id: "likes", label: "좋아요 한 글" }, + { id: "bookmarks", label: "북마크" }, +] as const; + +export type MenuItemId = (typeof MENU_ITEMS)[number]["id"]; diff --git a/src/constants/profile.ts b/src/constants/profile.ts new file mode 100644 index 0000000..ae5f151 --- /dev/null +++ b/src/constants/profile.ts @@ -0,0 +1,12 @@ +export const DEVELOPER_TABS = [ + { + value: "profile", + label: "프로필", + }, + { + value: "posts", + label: "작성한 글 ", + }, +] as const; + +export type DeveloperTabValue = (typeof DEVELOPER_TABS)[number]["value"]; diff --git a/src/main.tsx b/src/main.tsx index a778dd7..847eeb8 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -5,6 +5,8 @@ import "./index.css"; import App from "./App.tsx"; import { LoginPage } from "./pages/auth/LoginPage.tsx"; import { BoardPage } from "./pages/home/index.tsx"; +import { MyPage } from "./pages/my/index.tsx"; +import { DeveloperPage } from "./pages/developer/index.tsx"; import { ExplorePage } from "./pages/explore/index.tsx"; async function enableMocking() { @@ -31,6 +33,14 @@ const router = createBrowserRouter([ path: "explore", element: , }, + { + path: "my", + element: , + }, + { + path: "developer/:id", + element: , + }, ], }, { diff --git a/src/pages/developer/_components/Posts.tsx b/src/pages/developer/_components/Posts.tsx new file mode 100644 index 0000000..9ec48d4 --- /dev/null +++ b/src/pages/developer/_components/Posts.tsx @@ -0,0 +1,5 @@ +const Posts = () => { + return

작성글

; +}; + +export default Posts; diff --git a/src/pages/developer/_components/Profile.tsx b/src/pages/developer/_components/Profile.tsx new file mode 100644 index 0000000..8442bc3 --- /dev/null +++ b/src/pages/developer/_components/Profile.tsx @@ -0,0 +1,5 @@ +const Profile = () => { + return

프로필

; +}; + +export default Profile; diff --git a/src/pages/developer/index.tsx b/src/pages/developer/index.tsx new file mode 100644 index 0000000..3e2cea8 --- /dev/null +++ b/src/pages/developer/index.tsx @@ -0,0 +1,34 @@ +import { useState } from "react"; +import { AppTabs } from "@/components/common/AppTabs"; +import { ProfileSection } from "@/components/profile/ProfileSection.tsx"; +import type { DeveloperTabValue } from "@/constants/profile"; +import { DEVELOPER_TABS } from "@/constants/profile"; +import Posts from "./_components/Posts.tsx"; +import Profile from "./_components/Profile.tsx"; + +export const DeveloperPage = () => { + const [activeTab, setActiveTab] = useState("profile"); + + const handleTabChange = (value: DeveloperTabValue) => { + setActiveTab(value); + }; + + return ( +
+
+ +
+ +
+ {activeTab === "profile" && } + {activeTab === "posts" && } +
+
+ ); +}; diff --git a/src/pages/my/index.tsx b/src/pages/my/index.tsx new file mode 100644 index 0000000..458e41a --- /dev/null +++ b/src/pages/my/index.tsx @@ -0,0 +1,28 @@ +import { ProfileSection } from "@/components/profile/ProfileSection"; +import { ChevronRight } from "lucide-react"; +import { MENU_ITEMS, type MenuItemId } from "@/constants/my"; + +export const MyPage = () => { + const handleMenuItemClick = (menuId: MenuItemId) => { + console.log(`선택된 메뉴: ${menuId}`); + }; + + return ( +
+ +
+
    + {MENU_ITEMS.map((item) => ( +
  • handleMenuItemClick(item.id)} + className="flex justify-between items-center py-4 border-b border-brand-surface cursor-pointer hover:bg-brand-surface/50 transition-colors"> + {item.label} + +
  • + ))} +
+
+
+ ); +};