├── src ├── shared │ ├── api │ │ ├── requestHeader │ │ │ └── .gitkeep │ │ ├── responseHandler │ │ │ └── .gitkeep │ │ └── profileApi.ts │ ├── design │ │ ├── index.ts │ │ └── color │ │ │ └── StartHubColors.ts │ ├── hooks │ │ ├── Profile │ │ │ ├── index.ts │ │ │ ├── useProfile.ts │ │ │ └── useUpdateProfile.ts │ │ ├── Onboarding │ │ │ ├── useEarlyOnboarding.ts │ │ │ ├── usePreOnboarding.ts │ │ │ └── useOnboarding.ts │ │ ├── useTypingEffect.ts │ │ └── Business │ │ │ └── useBusinessFrom.ts │ ├── types │ │ ├── BaseResponse.ts │ │ ├── ReissueResponse.ts │ │ └── ProfileTypes.ts │ ├── ui │ │ ├── index.ts │ │ ├── Toast │ │ │ ├── toastUtil.ts │ │ │ └── index.tsx │ │ ├── Banner │ │ │ └── index.tsx │ │ ├── Portal │ │ │ └── index.tsx │ │ ├── FoldArrow │ │ │ ├── style.ts │ │ │ └── index.tsx │ │ ├── BlockedRoute │ │ │ └── index.tsx │ │ ├── LoadingModal │ │ │ ├── index.tsx │ │ │ └── style.ts │ │ ├── Layout │ │ │ └── index.tsx │ │ ├── BmcList │ │ │ └── style.ts │ │ ├── BmcSelection │ │ │ ├── style.ts │ │ │ ├── index.tsx │ │ │ └── BmcSelectionSkeleton.tsx │ │ ├── pagination │ │ │ └── style.ts │ │ ├── CompetitorBmcCard │ │ │ ├── index.tsx │ │ │ └── style.ts │ │ ├── NoticeSkeleton │ │ │ └── index.tsx │ │ ├── SectionBlock │ │ │ └── index.tsx │ │ ├── BmcCard │ │ │ ├── index.tsx │ │ │ └── style.ts │ │ ├── CheckBox │ │ │ └── index.tsx │ │ ├── AdBanner │ │ │ └── index.tsx │ │ ├── HiringCard │ │ │ ├── style.ts │ │ │ └── index.tsx │ │ ├── TypeHangul │ │ │ └── index.tsx │ │ ├── CompetitorTemplateCard │ │ │ └── CompetitorCardSkeleton.tsx │ │ └── NoticeCard │ │ │ └── style.ts │ ├── lib │ │ ├── validation │ │ │ ├── email.ts │ │ │ └── password.ts │ │ └── utils │ │ │ └── cookieUtils.ts │ ├── utils │ │ ├── ScrollToTop │ │ │ └── scrollToTop.tsx │ │ └── Category │ │ │ └── jobCategory.tsx │ └── style │ │ └── webfont.style.ts ├── widgets │ └── bmc │ │ ├── index.ts │ │ ├── BmcContent │ │ ├── index.ts │ │ └── ui │ │ │ └── index.tsx │ │ └── BmcCanvas │ │ └── index.ts ├── app │ ├── types │ │ ├── vite-env.d.ts │ │ └── svg.d.ts │ ├── index.css │ ├── App.tsx │ └── model │ │ └── stores │ │ └── useAuthStore.ts ├── features │ ├── bmc │ │ ├── stepForm │ │ │ ├── index.ts │ │ │ ├── model │ │ │ │ └── types.ts │ │ │ └── ui │ │ │ │ ├── BmcGeneratingSkeleton │ │ │ │ └── index.tsx │ │ │ │ ├── Message │ │ │ │ ├── style.ts │ │ │ │ └── index.tsx │ │ │ │ └── style.ts │ │ ├── stepNavigate │ │ │ ├── index.ts │ │ │ └── model │ │ │ │ └── types.ts │ │ └── detail │ │ │ ├── index.ts │ │ │ ├── ui │ │ │ └── BmcLoadingState.tsx │ │ │ └── hooks │ │ │ └── useBmcData.ts │ ├── auth │ │ ├── social │ │ │ └── model │ │ │ │ ├── useNaverSignIn.ts │ │ │ │ ├── useAppleSignIn.ts │ │ │ │ └── useGoogleSignIn.ts │ │ ├── oauth │ │ │ ├── ui │ │ │ │ └── OAuthCallback │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── style.ts │ │ │ └── model │ │ │ │ └── useOAuthCallback.ts │ │ ├── getProfile │ │ │ └── model │ │ │ │ └── useGetMyProfile.ts │ │ ├── signUp │ │ │ ├── ui │ │ │ │ └── SignUpForm │ │ │ │ │ ├── PasswordSection │ │ │ │ │ └── style.ts │ │ │ │ │ └── AgreementSection │ │ │ │ │ ├── style.ts │ │ │ │ │ └── index.tsx │ │ │ ├── model │ │ │ │ └── useSignUp.ts │ │ │ └── constants │ │ │ │ └── signup.constants.ts │ │ └── signIn │ │ │ ├── ui │ │ │ └── SignInForm │ │ │ │ └── style.ts │ │ │ └── model │ │ │ └── useSignIn.ts │ ├── profile │ │ └── users │ │ │ ├── utils │ │ │ └── profileDisplayHelpers.ts │ │ │ ├── profileForm │ │ │ ├── ui │ │ │ │ └── NotMyPage │ │ │ │ │ └── index.tsx │ │ │ └── style.ts │ │ │ ├── sideBar │ │ │ └── style.ts │ │ │ └── likeListForm │ │ │ └── style.ts │ ├── notice │ │ ├── ui │ │ │ └── searchNotice │ │ │ │ └── style.ts │ │ ├── getNotice │ │ │ └── useGetNotice.ts │ │ ├── getNoticeSearch │ │ │ └── useGetNoticeSearch.ts │ │ ├── getNoticeDetail │ │ │ └── useGetNoticeDetail.ts │ │ ├── getNoticeRecommend │ │ │ └── useGetNoticeRecommend.ts │ │ ├── getLikedAnnouncements │ │ │ └── useGetLikedAnnouncements.ts │ │ ├── NoticeLike │ │ │ └── useNoticeLike.ts │ │ └── NoticeUnlike │ │ │ └── useNoticeUnlike.ts │ ├── post │ │ └── getPostAll │ │ │ └── model │ │ │ └── useGetCompanyPost.ts │ ├── mainMenu │ │ └── ui │ │ │ ├── style.ts │ │ │ └── index.tsx │ ├── competitor │ │ ├── getCompetitorAnalyses │ │ │ └── useGetCompetitorAnalyses.ts │ │ └── marketAnalysis │ │ │ ├── ui │ │ │ ├── UserScaleSection │ │ │ │ ├── style.ts │ │ │ │ └── index.tsx │ │ │ ├── CompetitorCard │ │ │ │ ├── index.tsx │ │ │ │ └── style.ts │ │ │ ├── BmcSidebar │ │ │ │ └── constants.ts │ │ │ └── InsightSection │ │ │ │ └── style.ts │ │ │ └── utils │ │ │ └── textFormatter.tsx │ ├── onboarding │ │ ├── preOnboarding │ │ │ └── index.tsx │ │ └── categorySelector │ │ │ └── index.tsx │ └── boxMenu │ │ └── ui │ │ └── index.tsx ├── assets │ ├── logo │ │ └── index.ts │ ├── icons │ │ ├── ai.png │ │ ├── bmc.png │ │ ├── card.png │ │ ├── heart.png │ │ ├── image.png │ │ ├── rival.png │ │ ├── checkbox.svg │ │ ├── naver.svg │ │ ├── index.ts │ │ ├── filledCheckbox.svg │ │ ├── fill_heart.svg │ │ ├── fi-sr-user.svg │ │ ├── fi-sr-user-blue.svg │ │ ├── bmc │ │ │ ├── customer-segments.svg │ │ │ ├── index.ts │ │ │ ├── cost-structure.svg │ │ │ ├── value-proposition.svg │ │ │ ├── channels.svg │ │ │ ├── key-partnerships.svg │ │ │ └── business-idea.svg │ │ ├── page-arrow-right.svg │ │ ├── page-arrow-hover-right.svg │ │ ├── page-arrow-left.svg │ │ ├── page-arrow-hover.svg │ │ ├── call.svg │ │ ├── profile.svg │ │ ├── location.svg │ │ ├── apple.svg │ │ ├── arrow.svg │ │ ├── fold-arrow.svg │ │ ├── check.svg │ │ ├── chevron-down.svg │ │ ├── plus.svg │ │ ├── email.svg │ │ ├── fi-sr-credit-card.svg │ │ ├── fi-sr-credit-card-blue.svg │ │ ├── LikeIcon.svg │ │ ├── fi-sr-diamond.svg │ │ ├── fi-sr-diamond-blue.svg │ │ ├── fi-sr-truck-side.svg │ │ ├── fi-sr-truck-side-blue.svg │ │ ├── fi-sr-link.svg │ │ ├── fi-sr-link-blue.svg │ │ └── share.svg │ ├── images │ │ ├── bmc에시.png │ │ ├── image.png │ │ ├── nouser.png │ │ ├── aiNotice.png │ │ ├── defaultProfile.png │ │ ├── user-profile.svg │ │ ├── templates │ │ │ └── no-image.svg │ │ └── stars.svg │ ├── category │ │ ├── software.svg │ │ ├── map.svg │ │ ├── person.svg │ │ ├── commerce.svg │ │ ├── camera.svg │ │ ├── fund.svg │ │ ├── education.svg │ │ └── coin.svg │ └── tag │ │ └── electron.svg ├── entities │ ├── user │ │ ├── queryKey.ts │ │ ├── api │ │ │ ├── business.ts │ │ │ └── user.ts │ │ └── model │ │ │ ├── business.ts │ │ │ ├── validation.ts │ │ │ └── useEmailVerification.ts │ ├── post │ │ ├── queryKey.ts │ │ ├── api │ │ │ └── postApi.ts │ │ └── model │ │ │ └── post.types.ts │ ├── competitor │ │ ├── queryKey.ts │ │ ├── api │ │ │ └── competitor.ts │ │ └── model │ │ │ └── types.ts │ ├── bmc │ │ ├── model │ │ │ ├── useBmcQuestions.ts │ │ │ ├── useCreateSessions.ts │ │ │ └── localTypes.ts │ │ ├── index.ts │ │ └── ui │ │ │ ├── BmcCreateButton │ │ │ ├── index.tsx │ │ │ └── style.ts │ │ │ └── BmcTemplateCard │ │ │ └── style.ts │ └── notice │ │ ├── queryKey.ts │ │ ├── model │ │ └── notice.type.ts │ │ └── api │ │ └── notice.ts ├── pages │ ├── Bmc │ │ ├── BmcPage │ │ │ ├── style.ts │ │ │ └── index.tsx │ │ └── BmcGeneratePage │ │ │ ├── style.ts │ │ │ └── index.tsx │ ├── Callback │ │ └── index.tsx │ ├── Competitor │ │ ├── index.tsx │ │ ├── BmcSelection │ │ │ └── index.tsx │ │ └── List │ │ │ └── index.tsx │ ├── LikeList │ │ └── index.tsx │ ├── MyProfile │ │ └── index.tsx │ ├── Main │ │ ├── style.ts │ │ ├── ui │ │ │ └── MainContent │ │ │ │ └── style.ts │ │ └── index.tsx │ ├── EditProfile │ │ └── index.tsx │ ├── SignIn │ │ ├── style.ts │ │ └── index.tsx │ ├── Notice │ │ └── style.ts │ ├── NoticeDetail │ │ └── index.tsx │ ├── SignUp │ │ └── style.ts │ ├── CompetitorAnalysis │ │ └── index.tsx │ └── Onboarding │ │ ├── style.ts │ │ ├── early │ │ └── style.ts │ │ └── pre │ │ └── style.ts └── main.tsx ├── tsconfig.node.tsbuildinfo ├── public ├── robots.txt └── starthub-opengraph.png ├── vercel.json ├── .vercel ├── project.json └── README.txt ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── .gitignore ├── tsconfig.node.json ├── tsconfig.json ├── eslint.config.js ├── package.json ├── tsconfig.app.json └── vite.config.ts /src/shared/api/requestHeader/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/shared/api/responseHandler/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/widgets/bmc/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BmcContent'; -------------------------------------------------------------------------------- /src/app/types/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /tsconfig.node.tsbuildinfo: -------------------------------------------------------------------------------- 1 | {"root":["./vite.config.ts"],"version":"5.8.3"} -------------------------------------------------------------------------------- /src/widgets/bmc/BmcContent/index.ts: -------------------------------------------------------------------------------- 1 | export { default as BmcContent } from "./ui"; -------------------------------------------------------------------------------- /src/features/bmc/stepForm/index.ts: -------------------------------------------------------------------------------- 1 | export { default as BmcStepForm } from "./ui"; 2 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | Sitemap: https://start-hub.kr/sitemap.xml -------------------------------------------------------------------------------- /src/app/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } -------------------------------------------------------------------------------- /src/assets/logo/index.ts: -------------------------------------------------------------------------------- 1 | export { ReactComponent as StartHubLogo } from "./logo.svg"; 2 | -------------------------------------------------------------------------------- /src/features/bmc/stepNavigate/index.ts: -------------------------------------------------------------------------------- 1 | export { default as BmcStepNavigate } from "./ui"; 2 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }] 3 | } -------------------------------------------------------------------------------- /.vercel/project.json: -------------------------------------------------------------------------------- 1 | {"projectId":"prj_ias8ABz329dal36M1tK9jXdFKCTC","orgId":"team_jYx7eiTuWZgnHKM5ehtepEJN"} -------------------------------------------------------------------------------- /src/widgets/bmc/BmcCanvas/index.ts: -------------------------------------------------------------------------------- 1 | export { BmcCanvas } from './BmcCanvas'; 2 | export * from './style'; 3 | -------------------------------------------------------------------------------- /src/assets/icons/ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/src/assets/icons/ai.png -------------------------------------------------------------------------------- /src/assets/icons/bmc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/src/assets/icons/bmc.png -------------------------------------------------------------------------------- /src/assets/icons/card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/src/assets/icons/card.png -------------------------------------------------------------------------------- /src/assets/icons/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/src/assets/icons/heart.png -------------------------------------------------------------------------------- /src/assets/icons/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/src/assets/icons/image.png -------------------------------------------------------------------------------- /src/assets/icons/rival.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/src/assets/icons/rival.png -------------------------------------------------------------------------------- /public/starthub-opengraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/public/starthub-opengraph.png -------------------------------------------------------------------------------- /src/assets/images/bmc에시.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/src/assets/images/bmc에시.png -------------------------------------------------------------------------------- /src/assets/images/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/src/assets/images/image.png -------------------------------------------------------------------------------- /src/assets/images/nouser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/src/assets/images/nouser.png -------------------------------------------------------------------------------- /src/assets/images/aiNotice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/src/assets/images/aiNotice.png -------------------------------------------------------------------------------- /src/entities/user/queryKey.ts: -------------------------------------------------------------------------------- 1 | export const USER_QUERY_KEYS = { 2 | user: { 3 | getUserProfile: ["user", "me"], 4 | }, 5 | }; -------------------------------------------------------------------------------- /src/assets/images/defaultProfile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JinInSaDaeCheonMyeong/starthub-web/HEAD/src/assets/images/defaultProfile.png -------------------------------------------------------------------------------- /src/shared/design/index.ts: -------------------------------------------------------------------------------- 1 | export { StartHubColors } from "./color/StartHubColors" 2 | export { StartHubFont } from "./text/StartHubFont"; 3 | -------------------------------------------------------------------------------- /src/entities/post/queryKey.ts: -------------------------------------------------------------------------------- 1 | export const POST_QUERY_KEYS = Object.freeze({ 2 | post: { 3 | getCompanyPost: ['company', 'all'] 4 | }, 5 | }); 6 | -------------------------------------------------------------------------------- /src/shared/hooks/Profile/index.ts: -------------------------------------------------------------------------------- 1 | export { useProfile, PROFILE_QUERY_KEY } from './useProfile'; 2 | export { useUpdateProfile } from './useUpdateProfile'; 3 | -------------------------------------------------------------------------------- /src/shared/types/BaseResponse.ts: -------------------------------------------------------------------------------- 1 | export interface BaseResponse { 2 | data: T; 3 | status: string; 4 | message: string; 5 | statusCode: number; 6 | } -------------------------------------------------------------------------------- /src/shared/types/ReissueResponse.ts: -------------------------------------------------------------------------------- 1 | export interface ReissueResponse { 2 | error: string; 3 | message: string; 4 | status: number; 5 | timestamp: string; 6 | } -------------------------------------------------------------------------------- /src/shared/ui/index.ts: -------------------------------------------------------------------------------- 1 | export { StartHubButton } from "./Button"; 2 | export { StartHubTextField } from "./TextField"; 3 | export { StartHubCheckBox } from "./CheckBox"; -------------------------------------------------------------------------------- /src/entities/competitor/queryKey.ts: -------------------------------------------------------------------------------- 1 | export const COMPETITOR_QUERY_KEYS = { 2 | competitor: { 3 | getAnalyses: ['competitor', 'analyses'] as const, 4 | }, 5 | } as const; 6 | -------------------------------------------------------------------------------- /src/shared/lib/validation/email.ts: -------------------------------------------------------------------------------- 1 | export const isValidEmail = (email: string): boolean => { 2 | const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 3 | return emailRegex.test(email); 4 | }; -------------------------------------------------------------------------------- /src/pages/Bmc/BmcPage/style.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const PageLayout = styled.div` 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | `; 8 | -------------------------------------------------------------------------------- /src/assets/icons/checkbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/pages/Callback/index.tsx: -------------------------------------------------------------------------------- 1 | import OAuthCallback from "@/features/auth/oauth/ui/OAuthCallback"; 2 | 3 | const CallbackPage = () => { 4 | return ; 5 | }; 6 | 7 | export default CallbackPage; 8 | -------------------------------------------------------------------------------- /src/assets/icons/naver.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/shared/ui/Toast/toastUtil.ts: -------------------------------------------------------------------------------- 1 | import { toast } from "react-toastify"; 2 | 3 | export const showSuccessToast = (message: string) => 4 | toast.success(message); 5 | 6 | export const showErrorToast = (message: string) => 7 | toast.error(message); -------------------------------------------------------------------------------- /src/features/auth/social/model/useNaverSignIn.ts: -------------------------------------------------------------------------------- 1 | import { toast } from "react-toastify"; 2 | 3 | export const useNaverSignIn = () => { 4 | const handleNaverSignIn = () => { 5 | toast.error('개발 중인 기능입니다.') 6 | } 7 | return { handleNaverSignIn } 8 | }; -------------------------------------------------------------------------------- /src/shared/lib/validation/password.ts: -------------------------------------------------------------------------------- 1 | export const isValidPassword = (password: string): boolean => { 2 | const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; 3 | return passwordRegex.test(password); 4 | }; -------------------------------------------------------------------------------- /src/features/auth/social/model/useAppleSignIn.ts: -------------------------------------------------------------------------------- 1 | import { toast } from "react-toastify"; 2 | 3 | export const useAppleSignIn = () => { 4 | const handleAppleSignIn = () => { 5 | toast.error('개발 중인 기능입니다.') 6 | } 7 | return { handleAppleSignIn } 8 | }; -------------------------------------------------------------------------------- /src/entities/bmc/model/useBmcQuestions.ts: -------------------------------------------------------------------------------- 1 | import useQuestionStore from "@/entities/bmc/model/useQuestionStore"; 2 | 3 | export const useBmcQuestions = () => { 4 | const { loadQuestions, isLoading } = useQuestionStore(); 5 | 6 | return { bmcQuestions: loadQuestions, isLoading }; 7 | }; -------------------------------------------------------------------------------- /src/shared/ui/Banner/index.tsx: -------------------------------------------------------------------------------- 1 | import BannerImg from "@assets/images/image.png"; 2 | 3 | const Banner = () => { 4 | return ( 5 | <> 6 | banner 7 | 8 | ); 9 | }; 10 | export default Banner; 11 | -------------------------------------------------------------------------------- /src/pages/Competitor/index.tsx: -------------------------------------------------------------------------------- 1 | import BmcSelection from "@/shared/ui/BmcSelection"; 2 | import Layout from "@/shared/ui/Layout"; 3 | 4 | const Competitor = () => { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | }; 11 | 12 | export default Competitor; 13 | -------------------------------------------------------------------------------- /src/app/types/svg.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.svg' { 2 | import * as React from 'react'; 3 | 4 | export const ReactComponent: React.FunctionComponent< 5 | React.SVGProps & { title?: string } 6 | >; 7 | 8 | const src: string; 9 | export default src; 10 | } 11 | -------------------------------------------------------------------------------- /src/features/bmc/detail/index.ts: -------------------------------------------------------------------------------- 1 | export { BmcActionButtons } from './ui/BmcActionButtons'; 2 | export { BmcLoadingState } from './ui/BmcLoadingState'; 3 | export { useBmcData } from './hooks/useBmcData'; 4 | export { useBmcCapture } from './hooks/useBmcCapture'; 5 | export { useBmcEdit } from './hooks/useBmcEdit'; -------------------------------------------------------------------------------- /src/pages/LikeList/index.tsx: -------------------------------------------------------------------------------- 1 | import LikeListForm from "@/features/profile/users/likeListForm" 2 | import Layout from "@/shared/ui/Layout"; 3 | 4 | const LikeList = () => { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | }; 11 | 12 | export default LikeList; 13 | -------------------------------------------------------------------------------- /src/pages/MyProfile/index.tsx: -------------------------------------------------------------------------------- 1 | import ProfileForm from "@/features/profile/users/profileForm"; 2 | import Layout from "@/shared/ui/Layout"; 3 | 4 | const MyProfile = () => { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | } 11 | 12 | export default MyProfile 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## 📌 어떤 기능인가요? 11 | 12 | > 추가하려는 기능에 대해 간결하게 설명해주세요 13 | 14 | ## ✏️ 작업 상세 내용 15 | 16 | - [ ] TODO 17 | 18 | ## 📄 참고할만한 자료(선택) 19 | -------------------------------------------------------------------------------- /src/assets/icons/index.ts: -------------------------------------------------------------------------------- 1 | export { ReactComponent as Google } from "./google.svg"; 2 | export { ReactComponent as Apple } from "./apple.svg"; 3 | export { ReactComponent as Naver } from "./naver.svg"; 4 | export { ReactComponent as EyeIcon } from "./eye.svg"; 5 | export { ReactComponent as EyeOffIcon} from "./eye.slash.svg" 6 | -------------------------------------------------------------------------------- /src/pages/Main/style.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const PageLayout = styled.div` 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | `; 8 | 9 | export const CenteredBox = styled.div` 10 | display: flex; 11 | justify-content: center; 12 | width: 100%; 13 | `; -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## 🐛 어떤 버그인가요? 11 | 12 | > 어떤 버그인지 간결하게 설명해주세요 13 | 14 | ## 🤩 예상 결과 15 | 16 | > 예상했던 정상적인 결과가 어떤 것이었는지 설명해주세요 17 | 18 | ## 📄 참고할만한 자료(선택) 19 | -------------------------------------------------------------------------------- /src/pages/Competitor/BmcSelection/index.tsx: -------------------------------------------------------------------------------- 1 | import BmcList from "@/shared/ui/BmcSelection"; 2 | import Layout from "@/shared/ui/Layout"; 3 | 4 | const CompetitorBmcSelection = () => { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | }; 11 | 12 | export default CompetitorBmcSelection; 13 | -------------------------------------------------------------------------------- /src/pages/EditProfile/index.tsx: -------------------------------------------------------------------------------- 1 | import EditProfileForm from "@/features/profile/users/editProfileForm"; 2 | import Layout from "@/shared/ui/Layout"; 3 | 4 | const EditMyProfile = () => { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | }; 11 | 12 | export default EditMyProfile; 13 | -------------------------------------------------------------------------------- /src/entities/bmc/index.ts: -------------------------------------------------------------------------------- 1 | export { useBmcStore } from './model/useBmcStore'; 2 | export type { LocalBmcStep, LocalStepData, LocalBmcStore } from './model/localTypes'; 3 | export type { 4 | BmcResponseData, 5 | Question, 6 | CreateSessionRequest, 7 | CompetitorBmcSessionData, 8 | CompetitorBmcData 9 | } from './model/types'; 10 | -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import './app/index.css' 4 | import App from './app/App' 5 | import 'react-toastify/dist/ReactToastify.css'; 6 | 7 | createRoot(document.getElementById('root')!).render( 8 | 9 | 10 | 11 | ) 12 | -------------------------------------------------------------------------------- /src/assets/icons/filledCheckbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/features/bmc/stepForm/model/types.ts: -------------------------------------------------------------------------------- 1 | import { LocalBmcStep } from "@/entities/bmc/model/localTypes"; 2 | 3 | export interface StepFormProps { 4 | stepId: LocalBmcStep; 5 | title: string; 6 | description: string; 7 | placeholder: string; 8 | } 9 | 10 | export interface StepFormState { 11 | answer: string; 12 | isSubmitting: boolean; 13 | } 14 | -------------------------------------------------------------------------------- /src/shared/utils/ScrollToTop/scrollToTop.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | import { useLocation } from "react-router-dom"; 3 | 4 | const ScrollToTop = () => { 5 | const { pathname } = useLocation(); 6 | 7 | useEffect(() => { 8 | window.scrollTo(0, 0); 9 | }, [pathname]); 10 | 11 | return null; 12 | }; 13 | 14 | export default ScrollToTop; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | .env 26 | .env.* -------------------------------------------------------------------------------- /src/entities/bmc/ui/BmcCreateButton/index.tsx: -------------------------------------------------------------------------------- 1 | import { ReactComponent as Plus } from "@assets/icons/plus.svg"; 2 | import * as S from './style' 3 | 4 | const BmcCreateButton = () => { 5 | return ( 6 | {}}> 7 | 8 | 9 | 10 | 11 | ) 12 | } 13 | 14 | export default BmcCreateButton -------------------------------------------------------------------------------- /src/features/bmc/stepNavigate/model/types.ts: -------------------------------------------------------------------------------- 1 | import { LocalBmcStep } from "@/entities/bmc/model/localTypes"; 2 | 3 | export interface StepItem { 4 | id: LocalBmcStep; 5 | icon: React.ComponentType; 6 | label: string; 7 | subLabel?: string; 8 | description?: string; 9 | } 10 | 11 | export interface StepStateProps { 12 | $isCompleted?: boolean; 13 | $isCurrent?: boolean; 14 | } 15 | -------------------------------------------------------------------------------- /src/features/auth/oauth/ui/OAuthCallback/index.tsx: -------------------------------------------------------------------------------- 1 | import { Container, Message } from "./style"; 2 | import { useOAuthCallback } from "@/features/auth/oauth/model/useOAuthCallback"; 3 | 4 | const OAuthCallback = () => { 5 | useOAuthCallback(); 6 | 7 | return ( 8 | 9 | 로그인 중... 10 | 11 | ); 12 | }; 13 | 14 | export default OAuthCallback; -------------------------------------------------------------------------------- /src/shared/ui/Portal/index.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react'; 2 | import { createPortal } from 'react-dom'; 3 | 4 | interface PortalProps { 5 | children: ReactNode; 6 | } 7 | 8 | const Portal = ({ children }: PortalProps) => { 9 | const portalRoot = document.getElementById('portal-root') || document.body; 10 | return createPortal(children, portalRoot); 11 | }; 12 | 13 | export default Portal; -------------------------------------------------------------------------------- /src/entities/post/api/postApi.ts: -------------------------------------------------------------------------------- 1 | import StartHubAxios from "@/shared/api/customAxios/StartHubAxios"; 2 | import {postData } from "../model/post.types"; 3 | import { BaseResponse } from "@/shared/types/BaseResponse"; 4 | 5 | export const postApi = { 6 | getPostApp: async (): Promise => { 7 | const res: BaseResponse = await StartHubAxios.get(`/company/all`); 8 | return res.data; 9 | }, 10 | }; -------------------------------------------------------------------------------- /src/assets/icons/fill_heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/shared/design/color/StartHubColors.ts: -------------------------------------------------------------------------------- 1 | export const StartHubColors = Object.freeze({ 2 | // brandColors 3 | Primary: "#2466F4", 4 | Secondary: "#2D2D2D", 5 | 6 | //BlackColors 7 | Black1: "#000000", 8 | Black2: "#1F1F1F", 9 | White1: "#FFFFFF", 10 | White2: "#F5F5F5", 11 | 12 | //GrayColors 13 | Gray1: "#242424", 14 | Gray2: "#9B9B9B", 15 | Gray3: "#CFCFCF", 16 | Gray4: "#F3F4F6", 17 | 18 | //StateColors 19 | Error: "#EB5757", 20 | }); 21 | -------------------------------------------------------------------------------- /src/shared/types/ProfileTypes.ts: -------------------------------------------------------------------------------- 1 | export interface ProfileData { 2 | username: string; 3 | profileImage: string; 4 | companyIds: number[]; 5 | birth: string; 6 | gender: "MALE" | "FEMALE"; 7 | startupStatus: "PRE_STARTUP" | "STARTUP" | "SCALE_UP"; 8 | companyName: string; 9 | companyDescription: string; 10 | numberOfEmployees: number; 11 | companyWebsite: string; 12 | startupLocation: string; 13 | annualRevenue: number; 14 | startupFields: string[]; 15 | } -------------------------------------------------------------------------------- /src/assets/icons/fi-sr-user.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/shared/ui/FoldArrow/style.ts: -------------------------------------------------------------------------------- 1 | import { StartHubFont } from "@/shared/design"; 2 | import styled from "styled-components"; 3 | 4 | export const FoldArrowContainer = styled.div` 5 | display: flex; 6 | align-items: center; 7 | align-self: flex-start; 8 | margin-top: 60px; 9 | padding: 0 190px; 10 | span { 11 | ${StartHubFont.Pretendard.Headlines2.SemiBold} 12 | margin-left: 10px; 13 | } 14 | svg { 15 | width: 15px; 16 | cursor: pointer; 17 | } 18 | `; 19 | -------------------------------------------------------------------------------- /src/assets/icons/fi-sr-user-blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/entities/post/model/post.types.ts: -------------------------------------------------------------------------------- 1 | import { BaseResponse } from "@/shared/types/BaseResponse"; 2 | 3 | export interface postData { 4 | id: 0; 5 | companyName: string; 6 | companyDescription: string; 7 | companyCategory: 8 | | "CONTENT_MEDIA" 9 | | "FINTECH" 10 | | "HEALTHCARE_BIO" 11 | | "EDUCATION_EDUTECH" 12 | | "IT_SOFTWARE" 13 | | "ECOMMERCE" 14 | | "ETC"; 15 | logoImage: string; 16 | } 17 | 18 | export type postDataResponse= BaseResponse; 19 | -------------------------------------------------------------------------------- /src/pages/Main/ui/MainContent/style.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const ContentContainer = styled.div` 4 | width: 1040px; 5 | display: flex; 6 | justify-content: center; 7 | flex-direction: column; 8 | `; 9 | 10 | export const BoxMenuContainer = styled.div` 11 | display: flex; 12 | justify-content: center; 13 | margin-bottom: 40px; 14 | `; 15 | 16 | export const NoticeContainer = styled.div` 17 | display: flex; 18 | justify-content: center; 19 | margin-bottom: 30px; 20 | ` -------------------------------------------------------------------------------- /src/shared/hooks/Profile/useProfile.ts: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query'; 2 | import { profileApi } from '@/shared/api/profileApi'; 3 | import { ProfileData } from '@/shared/types/ProfileTypes'; 4 | 5 | export const PROFILE_QUERY_KEY = ['profile'] as const; 6 | 7 | export const useProfile = () => { 8 | return useQuery({ 9 | queryKey: PROFILE_QUERY_KEY, 10 | queryFn: profileApi.getUserProfile, 11 | staleTime: 1000 * 60 * 5, 12 | gcTime: 1000 * 60 * 30, 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /src/pages/SignIn/style.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { StartHubColors } from "@/shared/design/color/StartHubColors"; 3 | 4 | export const LeftBoxField = styled.div` 5 | background-color: ${StartHubColors.Primary}; 6 | width: 50%; 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | `; 11 | 12 | export const RightBoxField = styled.div` 13 | display: flex; 14 | position: relative; 15 | width: 50%; 16 | justify-content: center; 17 | align-items: center; 18 | `; -------------------------------------------------------------------------------- /src/features/profile/users/utils/profileDisplayHelpers.ts: -------------------------------------------------------------------------------- 1 | export const formatGender = (gender?: string | null): string => 2 | gender === "MALE" ? "남자" : gender === "FEMALE" ? "여자" : "-"; 3 | 4 | export const formatCurrency = (amount?: number | null): string => 5 | typeof amount === "number" ? `${amount.toLocaleString()}원` : "-"; 6 | 7 | export const formatEmployees = (count?: number | null): string => 8 | typeof count === "number" ? `${count}명` : "-"; 9 | 10 | export const safeValue = (value?: string | null): string => value || "-"; 11 | -------------------------------------------------------------------------------- /src/app/App.tsx: -------------------------------------------------------------------------------- 1 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; 2 | import Router from "@/app/router"; 3 | import { GlobalStyle } from "@/shared/style/webfont.style"; 4 | import GlobalToastContainer from "@/shared/ui/Toast"; 5 | 6 | const queryClient = new QueryClient(); 7 | 8 | function App() { 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | 18 | export default App; -------------------------------------------------------------------------------- /src/entities/notice/queryKey.ts: -------------------------------------------------------------------------------- 1 | import { NoticeParams, NoticeSearchParams } from "./model/notice.type"; 2 | 3 | export const NOTICE_QUERY_KEYS = { 4 | notice: { 5 | all: (params: NoticeParams) => ["notice", "all", params] as const, 6 | search: (params : NoticeSearchParams) => ["notice", "search", params] as const, 7 | likes: (params: NoticeParams) => ["notice", "likes", params] as const, 8 | getNoticeDetail: (id: number) => ["notice", "detail", id] as const, 9 | recommend: () => ["notice", "recommend"] as const, 10 | }, 11 | }; -------------------------------------------------------------------------------- /src/shared/style/webfont.style.ts: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from "styled-components"; 2 | 3 | export const GlobalStyle = createGlobalStyle` 4 | body { 5 | font-family: "Pretendard Variable","Wanted Sans Variable", "Wanted Sans", -apple-system, BlinkMacSystemFont, system-ui, "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif; 6 | user-select: none; 7 | } 8 | button, input, textarea { 9 | background-color: transparent; 10 | } 11 | `; 12 | 13 | -------------------------------------------------------------------------------- /src/assets/icons/bmc/customer-segments.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/pages/Notice/style.ts: -------------------------------------------------------------------------------- 1 | import { StartHubFont } from "@/shared/design"; 2 | import styled from "styled-components"; 3 | 4 | export const NoticeContentContainer = styled.div` 5 | margin-top: 50px; 6 | width: 100%; 7 | padding: 0 200px; 8 | min-height: 50vh; 9 | `; 10 | 11 | export const CardWrap = styled.div` 12 | display: flex; 13 | flex-wrap: wrap; 14 | `; 15 | 16 | export const ExceptionMessage = styled.p` 17 | ${StartHubFont.Pretendard.Body1.Medium} 18 | display: flex; 19 | justify-content: center; 20 | margin-top: 60px; 21 | `; 22 | -------------------------------------------------------------------------------- /.vercel/README.txt: -------------------------------------------------------------------------------- 1 | > Why do I have a folder named ".vercel" in my project? 2 | The ".vercel" folder is created when you link a directory to a Vercel project. 3 | 4 | > What does the "project.json" file contain? 5 | The "project.json" file contains: 6 | - The ID of the Vercel project that you linked ("projectId") 7 | - The ID of the user or team your Vercel project is owned by ("orgId") 8 | 9 | > Should I commit the ".vercel" folder? 10 | No, you should not share the ".vercel" folder with anyone. 11 | Upon creation, it will be automatically added to your ".gitignore" file. 12 | -------------------------------------------------------------------------------- /src/shared/ui/Toast/index.tsx: -------------------------------------------------------------------------------- 1 | import { Bounce, ToastContainer } from "react-toastify"; 2 | import "react-toastify/dist/ReactToastify.css"; 3 | 4 | const GlobalToastContainer = () => { 5 | return ( 6 | 19 | ); 20 | }; 21 | 22 | export default GlobalToastContainer; -------------------------------------------------------------------------------- /src/features/auth/oauth/ui/OAuthCallback/style.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { StartHubColors, StartHubFont } from "@/shared/design"; 3 | 4 | export const Container = styled.div` 5 | display: flex; 6 | justify-content: center; 7 | align-items: center; 8 | height: 100vh; 9 | `; 10 | 11 | export const Message = styled.p` 12 | color: ${StartHubColors.Gray2}; 13 | font-size: ${StartHubFont.Pretendard.Body1.Medium}; 14 | font-weight: ${StartHubFont.Pretendard.Body1.Medium}; 15 | font-family: ${StartHubFont.Pretendard.Body1.Medium}; 16 | margin: 0; 17 | `; -------------------------------------------------------------------------------- /src/shared/ui/BlockedRoute/index.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { useNavigate } from 'react-router-dom'; 3 | import { toast } from 'react-toastify'; 4 | 5 | interface BlockedRouteProps { 6 | message?: string; 7 | redirectTo?: string; 8 | } 9 | 10 | const BlockedRoute = ({ message, redirectTo = "/" }: BlockedRouteProps) => { 11 | const navigate = useNavigate(); 12 | 13 | useEffect(() => { 14 | toast.error(message); 15 | navigate(redirectTo); 16 | }, [message, redirectTo, navigate]); 17 | 18 | return null; 19 | }; 20 | 21 | export default BlockedRoute; -------------------------------------------------------------------------------- /src/assets/category/software.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | }, 22 | "include": ["vite.config.ts"] 23 | } 24 | -------------------------------------------------------------------------------- /src/pages/SignIn/index.tsx: -------------------------------------------------------------------------------- 1 | import * as S from "./style"; 2 | import SignInBox from "@/features/auth/signIn/ui/SignInForm"; 3 | import { ReactComponent as SignInImage } from "@assets/images/signInImage.svg"; 4 | 5 | const SignInPage = () => { 6 | return ( 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | ); 17 | }; 18 | 19 | export default SignInPage; 20 | -------------------------------------------------------------------------------- /src/shared/ui/LoadingModal/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import * as S from "./style"; 3 | 4 | interface LoadingModalProps { 5 | isOpen: boolean; 6 | message?: string; 7 | } 8 | 9 | const LoadingModal: React.FC = ({ 10 | isOpen, 11 | message = "로딩 중입니다..." 12 | }) => { 13 | if (!isOpen) return null; 14 | 15 | return ( 16 | 17 | 18 | 19 | {message} 20 | 21 | 22 | ); 23 | }; 24 | 25 | export default LoadingModal; 26 | -------------------------------------------------------------------------------- /src/pages/Main/index.tsx: -------------------------------------------------------------------------------- 1 | import Layout from "@/shared/ui/Layout"; 2 | import MainMenu from "@/features/mainMenu/ui"; 3 | import MainContent from "./ui/MainContent"; 4 | import * as S from "./style"; 5 | import Banner from "@/shared/ui/Banner"; 6 | import AdBanner from "@/shared/ui/AdBanner"; 7 | 8 | const MainPage = () => { 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ); 21 | }; 22 | 23 | export default MainPage; -------------------------------------------------------------------------------- /src/shared/ui/Layout/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Header from "@/widgets/Header"; 3 | import Footer from "@/widgets/Footer"; 4 | import styled from "styled-components"; 5 | 6 | interface LayoutProps { 7 | children: React.ReactNode; 8 | } 9 | 10 | const Layout = ({ children }: LayoutProps) => { 11 | return ( 12 | 13 |
14 | {children} 15 |